spring学习8-事务控制总结
默认那种异常会回滚事务:默认只有运行时异常会回滚事务,可以配置rollbackfor来指定回滚异常类型。
一、基于配置文件配置事务控制
1.1配置事务管理器
在容器中配置事务管理器,mybatis和jdbc对应的事务管理器是DataSourceTransactionManager
1.2配置事务属性
利用<tx:advice>
标签配置事务的属性,包括回滚异常,事务的传播行为等
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<!--指定事务的隔离级别,配置默认值是使用数据库的配置-->
<tx:method name="*" isolation="DEFAULT" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
1.3利用aop配置事务作用的方法
利用aop配置切入点
<aop:config>
<!--切点表达式要写详细,不能包含事务管理器等类,否则会报循环依赖-->
<aop:advisor advice-ref="txAdvice" pointcut="execution(public * com.lyy.service.*.*(..))"/>
</aop:config>
二、基于注解配置事务控制
2.1在配置类上开启注解事务支持
@EnableTransactionManagement
2.2配置事务管理器
利用@Bean
注解给容器中加入事务管理器
2.3利用@Transactional
注解指定哪个方法需要控制事务
三、xml+注解配置
将事物管理器配置在spring配置文件中,但还希望用@Transactional
注解来指定事务方法
需要在配置文件中开启spring对注解事务的支持
<tx:annotation-driven/>
四、编程式手动控制事务
在需要手动控制事务的类中注入事务管理器,利用事务管理器的方法来手动控制事务
@Autowired
private PlatformTransactionManager transactionManager;
public void testTransaction() throws Exception {
TransactionDefinition definition=new DefaultTransactionDefinition();
TransactionStatus transactionStatus = transactionManager.getTransaction(definition);
try {
User user=new User();
user.setId("1");
user.setAge(10);
userMapper.updateById(user);
int i=1;
if(i>0){
throw new Exception("受检异常");
}
user.setAge(20);
userMapper.updateById(user);
transactionManager.commit(transactionStatus);
} catch (Exception e) {
transactionManager.rollback(transactionStatus);
}
System.out.println("测试完成");
}
五、事务的传播行为
解决当一个事务方法被另一个事务方法调用时事务如何处理的问题。
有两个方法A,B,假设B的事务传播行为设置为以下几种(传播行为是设置在被调用的方法上的)
5.1 PROPAGATION_REQUIRED
如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
方法A调用方法B,如果A有事务,则B加入这个事务中运行,这时如果B抛出了异常,而A捕获了异常,就会发生
Transaction rolled back异常,因为B方法标记事务要回滚,而A方法标记事务要提交,产生了矛盾。
5.2 PROPAGATION_SUPPORTS
如果A存在一个事务,则B支持当前事务,如果A没有事务则B以非事务的模式运行。
5.3 PROPAGATION_MANDATORY
必要的,如果A存在事务,B加入当前事务,如果A没有事务,就会抛出异常
5.4 PROPAGATION_REQUIRES_NEW
新建,如果A存在事务,则先挂起,然后新建事务给B,A和B是两个独立的事务
5.5 PROPAGATION_NESTED
嵌套事务,如果A存在事务,则B以嵌套事务运行,如果A发生异常会回滚B,但如果B发生异常,且在A中捕获了异常,并不会回滚,也不会抛出Transaction rolled back异常
如果A没有事务,则B会新建一个事务
外层抛异常,会不会引起内层回滚: 会,外层抛异常不处理,会引起外层和内层回滚
内层抛异常不处理,会不会回滚外层: 会,内层和外层都会回滚,但如果A捕获了异常,A不会回滚
5.6 PROPAGATION_NOT_SUPPORTED
如果A有事务,则把A的事务挂起,B以非事务运行。
5.7 PROPAGATION_NEVER
从不。如果A有事务,就会抛出异常
5.8 Transaction rolled back异常的出现原因
如果A跟B用的是同一个事务(嵌套事务也算不是同一个事务),B抛出异常,标记事务状态为回滚,但在A中捕获了异常,这时A中会标记事务装填为提交,就会产生此异常。