Spring 事务回滚原理和方法
1、事务回滚
因为事务具有ACID特性,当在执行某个方法时,如果方法中有包含对数据库的插入或者更新操作,并且在当前事务上下文抛出了异常,spring会对已经进行的数据库操作“撤销”改变,恢复到原来的状态。
2、Spring事务工作原理
1)事务开始时,通过AOP机制,生成一个代理的connection对象,并将其放入DataSource实例的某个与DataSourceTransactionManager相关的容器中。在接下来的整个事务中,客户端与数据库的交互都使用该connection。
2)事务结束时,回滚在第一步中得到的代理的connection中的数据库命令,然后关闭该代理connection对象。
3、Spring事务注解@Transactional
@Transactional可以作用于接口、接口方法、类以及类方法上。当作用于类时,该类的所有的public方法都将具有事务的特性。但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外,@Transactional注解只能应用到public方法上,作用于protected、private时,会被忽略,也不会抛出任何异常,这是有Spring AOP的本质决定的。
此外,Spring声明式事务默认会对非检查型异常和运行时异常进行回滚,而对检查型异常不进行回滚操作。Error和RuntimeException及其子类为非检查型异常。如何改变默认规则?
1)让checked异常也进行回滚,需要加上(rollbackFor=Exception.class)
2)让unchecked异常也不回滚,加上(notRollbackFor=RunTimeException.class)
3)不需要事务,@Transactional(propagation=Propagation.NOT_SUPPORTED)
4)如果不添加rollbackFor等属性,Spring碰到Unchecked Exceptions都会回滚,不仅是RuntimeException,也包括Error。
4、虽然配置了rollbackFor属性,但是方法执行失败,还是没有进行回滚
1)类内部方法调用奔雷的其他方法,是不会引起事务的,因为不能被AOP捕获,即使被调用方法使用@Transactional注解进行修饰。
2)抛出异常,但是被catch住了
修改方法:
1)在catch语句中,继续抛出Exception。不建议这么做,很不友好
2)对于要进行事务的方法,不使用try catch,在上层调用的时候处理异常;
3)在catch语句中增加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常。
- 点赞
- 收藏
- 分享
- 文章举报
- spring事务不回滚throw的Exception异常的解决方法
- Spring事务不回滚,原理分析以及解决方案
- Spring中声明式事务的注解@Transactional的参数的总结(REQUIRED和REQUIRES_NEW的与主方法的回滚问题)
- spring的事务管理的原理(如何设置在Action或者在Service层进行事务拦截及其回滚)
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
- Spring异常捕获而且回滚事务的方法
- spring 控制事务下手动回滚事务的方法
- spring事务失效解决方法并进行事务的部分回滚
- spring事务控制的方法中抛出异常不回滚
- 初探hibernate和spring集成得事务控制原理,欢迎交流。
- Spring的事务管理对何种异常进行回滚
- xjl:Spring 事务管理原理探究
- Spring @async 方法上添加该注解实现异步调用的原理
- 事务的定义,事务的作用以及Spring事务原理
- Spring的事务管理难点剖析:事务方法嵌套调用的迷茫
- Junit加载Spring容器作单元测试_添加事务回滚
- spring事务不能回滚 异常捕获不抛出
- 请教spring事务控制回滚的问题
- spring事务原理解析
- PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)