Srping如何实现事务回滚
简介
spring支持编程式事务和声明式事务
编程式事务管理使用transactiontemepate
声明式事务是建立在aop之上的,其本质是通过aop的功能对方法前后进行拦截,也就是在目标方法开始前假如一个事务,在执行完目标方法后根据执行情况提交或者回滚事务
实际开发中声明式事务用的比较多
实现
spring的事务是由aop来实现的,先要生成具体的代理对象,然后按照aop的整套流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但在aop中不是通知来实现的,而是通过TransactionInterceptor然后调用invoke来实现具体的逻辑
- 先做准备工作,解析各个方法上的事务相关属性,根据具体的属性来判断是否开启新事务
- 当需要开启的时候,获取数据库连接,关闭自动提交功能,开启事务
- 执行具体的sql逻辑操作
- 在操作过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing来完成事务的回滚操作,回滚的具体逻辑是通过doRollBack方法来实现的,实现的时候也是要先获取连接对象,通过连接对象来回滚,最后调用jdbc的回滚逻辑
- 如果执行过程中,没有任何意外的情况发生,那么通过commitTransactionAfterReturning来完成事务的提交操作,提交的具体逻辑是通过docommit方法来实现的,实现的时候也要获取连接,通过连接的对象来提交
- 当事物执行完毕之后需要清除相关的事务信息cleanupTransactionInfo
事务传播
spring七种传播特性
REQUIRED,SUPPORTS,MANDATORY,REQUIRES_NEW,NOT_SUPPORTED,NEVER,NESTED
如果A方法调用B方法
支持当前事务
保证多个操作在同一个事务中
REQUIRED:默认值,如果当前A没有事务,就创建一个新事务,如果当前存在事务就加入该事务
SUPPORTS:支持事务,如果A中有事务,就使用A中的事务.如果A没有事物,不使用事务
MANDATORY:如果A当中有事务调用A当中的事务,如果A当中没有事务,直接抛出异常.
不支持当前事务
保证多个操作不在同一个事务当中
REQUIRES_NEW:如果A中有事务,将A的事务挂起(暂停),创建新的事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。(REQUIRES_NEW的这种情况,外层事物的异常不会影响内层事务,但内层事务的异常是会影响到外层事务。)
NOT_SUPPORTED:如果A中有事务,将A的事务挂起.不使用事物管理.B事物不会影响A
NEVER:如果A中有事务,报异常
嵌套事务
NESTED:嵌套事物,如果A中有事务,按照A的事务执行,执行完成之后,设置一个保存点
执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始的位置,也可以回滚到保存点
- 主事务和嵌套事务属于同一个事务
- 嵌套事务出错回滚不会影响到主事务
- 主事务回滚会将嵌套事务一起回滚了