您的位置:首页 > 编程语言 > Java开发

Spring 事务回滚原理和方法

2020-01-13 06:17 78 查看

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();语句,手动回滚,这样上层就无需去处理异常。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
楼下_小黑 发布了3 篇原创文章 · 获赞 0 · 访问量 222 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: