目录
[Spring] Spring 探秘 之 事务配置(一)
[capsule-spring-boot-transaction] Spring 探秘 之 事务配置
准备工作
>>> [Spring Boot] Spring boot 整合mybatis、postgresql [Gradle构建项目]
数据库事务简介
何为数据库事务?
是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务具有四个特性:原子性、一致性、隔离性、持久性。
- 原子性:表示组成一个事务的多个数据库操作是一个不可分割的原子单元。事务中的操作要么都发生,要么都不发生。
- 一致性:事务前后数据的完整性必须保持一致
- 隔离性:指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离,
- 持久性:指一个事务一旦被提交,它对数据库的数据的改变是永久的,即使数据库发生故障。
Spring声明式事务管理
概述
1、Spring 的声明式事务管理在底层是建立在 AOP 的基础上。其本质是在方法前后进行拦截,然后在目标方法开始之前创建一个事务,在执行这目标方法结束后,根据执行情况提交或进行回滚事务。
2、声明式事务最大的优点就是不需通过编程的方式而进行管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明,便可将事务规则应用到业务逻辑中。
3、声明式事务不足的地方在于,与编程式事务相比,只能作用到方法级别,无法像编程式事务那样可以作用到代码块级别
编程模板
Spring为事务管理提供了一致的编程模板,把事务处理的主要过程抽象出来,不管底层选择的是mybatis、hibernate操作数据库,都可以使用统一的事务编程模型。Spring通过AOP切面增强实现声明式事务处理的功能。
- 事务运行状态:org.springframework.transaction.TransactionStatus
- 事务定义信息(隔离级别、传播等):org.springframework.transaction.TransactionDefinition
- 事务同步管理器:org.springframework.transaction.PlatformTransactionManager
事务管理器的配置
Spring 将事务管理委托给底层具体的持久化实现框架来完成。因此,Spring为不同的持久化框架提供了PlatformTransactionManager 接口的实现类。
实现类 | 描述 |
---|---|
org.springframework.transaction.jta.JtaTransactionManager | 使用JPA进行持久化时,使用该事务管理器 |
org.springframework.orm.hibernate3.HibernateTransactionManager | 使用Hibernate X.0(X 可以为3/4/5)版本进行持久化时,使用该事务管理器 |
org.springframework.jdbc.datasource.DataSourceTransactionManager | 使用Spring JDBC 或 Mybatis 等基于DataSource数据源的持久化技术时,使用 该事务管理器 |
org.springframework.orm.jdo.JdoTransactionManager | 使用JDO进行持久化时 ,使用该事务管理器 |
org.springframework.transaction.jta.JtaTransactionManager | 具有多个数据源的全局事务使用该事务管理器(不管采用何种持久化技术) |
Spring将JDBC的Connection
、Hibernate的Session
等访问数据库的连接或会话对象统称为资源。这些资源在同一时刻是不能多线程共享的。为了让DAO
、Service
类能租到singleton
。
Spring的事务同步管理类org.springframework.transaction.support.TransactionSynchronization
使用ThreadLcoal
为不同事务线程提供了独立的资源副本,同时维护事务配置的属性和运行状态信息。事务同步管理器是Spring事务管理的基石,不管用户使用的是编程式事务管理,还是声明式事务管理,都离不开同步管理器。
Spring框架为不同的持久化技术提供了一套从TransactionSynchronization
中获取对应线程绑定资源的工具类,如下:
持久化技术 | 线程绑定资源获取工具 |
---|---|
Spring JDBC 或 Mybatis | org.springframework.jdbc.datasource.DataSourceUtils |
Hibernate X .0 | org.springframework.orm.hibernate3.SessionFactoryUtils |
JPA | org.springframework.orm.jpa.EntityManagerFactoryUtils |
JDO | org.springframework.orm.jdo.PersistenceManagerFactoryUtils |
Spring配置事务管理器和策略
xml形式
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务策略
1、<tx:advice>定义事务通知,用于指定事务属性,其中“transaction-manager”属性指定事务管理器,并通过<tx:attributes>指定具体需要拦截的方法
2、<tx:method>拦截方法,其中参数有:
name:方法名称,将匹配的方法注入事务管理,可用通配符(*)可以用来指定一批关联到相同的事务属性的方法。 如:'find*'、'handle*'、'on*Event'等等。
propagation:事务传播行为,
isolation:事务隔离级别定义;默认为“DEFAULT”
timeout:事务超时时间设置,单位为秒,默认-1,表示事务超时将依赖于底层事务系统;
read-only:事务只读设置,默认为false,表示不是只读;
rollback-for:需要触发回滚的异常定义,可定义多个,以“,”分割,默认任何RuntimeException都将导致事务回滚,而任何Checked Exception将不导致事务回滚;
no-rollback-for:不被触发进行回滚的 Exception(s);可定义多个,以“,”分割;
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception"/>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception"/>
<tx:method name="del*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="modify*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="handle*" propagation="NOT_SUPPORTED" read-only="false" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置事务切点
1、其中 and,or,需要注意大小写,可以写成 &&,||.
2、execution是Spring AOP中最主要的切入点指示符,该切入点的用法相对复杂,execution表达式的格式如下:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
上面格式中的execution是不变的,用于作为execution表达式的开头,整个表达式中的解释如下:
modifiers-pattern:指定方法的修饰符,支持通配符,该部分可以省略
ret-type-pattern:指定方法的返回值类型,支持通配符,可以使用"*"通配符来匹配所有的返回值类型。
declaring-type-pattern:指定方法所属的类,支持通配符,在包名之间的..代表当前包和其子包,该部分可以省略。
name-pattern:指定匹配指定的方法名,支持通配符,可以使用"*"通配符来匹配所有方法。
param-pattern:指定方法声明中的形参列表,支持两个通配符,即"*"和"..",其中“*”代表一个任意类型的参数,而“..”代表零个或多个任意类型的参数。例如,()匹配一个不接受任何参数的方法,而(..)匹配一个接受任意数量参数的方法,(*)匹配了一个接受一个任何类型的参数的方法,(*,String)匹配了一个接受两个参数的方法,其中第一个参数是任意类型,第二个参数必须是String类型。
throws-pattern:指定方法声明抛出的异常,支持通配符,该部分可以省略.
-->
<aop:config>
<aop:pointcut id="pc"
expression="(execution(* com.x.xx.xxx..*.service.*.*(..)))
or (execution(* com.x.xx.xxx..*.thread.*.*(..)))
or (execution(* com.x.xx.xxx..*.mq.*.*(..)))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
</aop:config>
说明:
异常的继承结构
:Throwable
为基类,Error
和Exception
继承Throwable
。Error
和RuntimeException
及其子类称为未检查异常(unchecked),其它异常成为已检查异常(checked)。事务配置
:告知数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。
Spring 事务传播规则
[Spring] Spring 探秘 之 事务配置(二) 请前往
>>> [Spring] Spring 探秘 之 事务配置(二)
REFRENCES
更多
扫码关注或搜索架构探险之道
获取最新文章,不积跬步无以至千里,坚持每周一更,坚持技术分享。我和你们一起成长 _ !