Spring 事物管理
Spring 中的事务管理分为两种形式,一种是编程式事务,一种是声明式事务.
编 程 式 事 务 在 项 目 中 很 少 使 用 , 这 种 方 式 需 要 注 入 一 个 事 务 管 理 对 象TransactionTemplate ,然后在我们代码中需要提交事务或回滚事务时自己写代码实现.
声明式事务 管理建立在 AOP 基础上,本质是对方法前后进行拦截,所以声明式事务是方法级别的。
Spring 声明式事物管理方式
Spring 声明式事物管理方式有两种:1.基于 xml 配置 2.基于注解实现
基于 xml 配置
<!--声明式事务, 配置spring事务管理 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!--配置spring事务传播行为, 这是spring框架自己特有的一个功能 那个方法需要进行就行了-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes><tx:method name="save" propagation="REQUIRED"/></tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="save" expression="execution(* com.qn.spring.dao.Userdao.*(..))())"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="save"></aop:advisor></aop:config>
<!--将Userdao类中的所有方法添加到spring框架管理中-->
注解方式
<!--注解方式实现事务管理配置-->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional
public void saveDept(){
deptdao.save();
commonService.saveLog();
}
Spring 事务传播行为
即然是传播,那么至少有两个东西,才可以发生传播。单体不存在传播这个行为。事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。事务传播行为是 Spring 框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.
例如:methodA 事务方法调用 methodB 事务方法时,methodB 是继续在调用者 methodA 的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB 的事务传播行为决定的。
Spring 定义了七种传播行为
1.PROPAGATION_REQUIRED 说明: 指定的方法必须在事务内执行,若当前存在事务,加入到当前事务中,若当前没有事务,则创建一个新事务,这种传播行为是最常见的,也是 spring 默认的传播行为.
2.PROPAGATION_SUPPORTS: 支持当前事务,如果当前没有事务,就以非事务方式执行。
3.PROPAGATION_REQUIRES_NEW: 总是新建一个事务,如果当前存在事务,把当前事务挂起,直到新建的事务结束。
4.PROPAGATION_MANDATORY :使用当前的事务,如果当前没有事务,就抛出异常。
5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER :以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIR类似的操作
声明式事务不生效的场景
- @Transactional 应用在非 public 修饰的方法上
- @Transactional 注解属性 propagation 设置错误
- 同一个类中方法调用,导致@Transactional 失效
- 异常被 catch 捕获导致@Transactional 失效