spring事务传播原理

spring事务很多人都知道是基于aop 切面实现的,在目标方法执行前

try{

connection.setAutoCommit(false);

@Transactional

目标方法A{

--》方法B{}

}

connection.setAutoCommit(true);

}catch(){

connection.rollback();

}finally{

connection.close();

}

这个大概的逻辑可能大部分人都知道,但是事务是怎么传递的呢,

当程序执行到内层方法B的时候,它怎么能感知方法A上面的事务注解,或者说程序怎么知道当前线程存在事务,

spring会使用ThreadLocal来保存当前线程的事务信息(就是@Transactional里面默认的值或者声明的值),包括事务的传播属性和隔离级别,回滚异常类型等。

中途插播一下关于connection的知识,这个对象就是一次会话,里面有一个sessionID标识,同一次事务共用一个connection对象。还有一个安全保存点概念要了解一下。connection.setSavepoint 就是代码执行一部分了,人为调用这行代码,以保证如果接下来出现异常也不会回滚安全点之前的操作。

写到这里就比较明白了,如果内层事务想和外层事务不相互影响,则要么就是使用不同connection,要么就是设置安全保存点,保证内层事务出现问题也不会回导致外层的事务回滚。

如果方法B上的事务注解上的传播属性为不支持事务的时候,其实就是先设置安全保存点,然后设置connection的是默认的自动提交模式connection.setAutoCommit(true);

如果B方法是传播属性为Propagation.REQUIRES_NEW,则是会新建一个connection,对于 数据库来说这两个connection完全没有关系,外层的错误将不会影响内层方法B,因为对于B来说是个独立的事务,它已经完事了,因为外层出现的异常不会抛到内层来,但是如果方法B抛出异常,则内层事务会回滚,因为异常被往外层抛出,则外层事务也一样回滚,本来这两个事情本来没啥关系,就是Java的异常抛出机制就是内层往外层丢出,没办法,伤及池鱼咯,先说这么多,相信你已经足够有能力应对面试官的拷问了。

connection 还告诉我们,所谓隔离级别,说白了就是这行代码connection.setTransactionIsolation(level);spring只是告诉连接对象说,我要使用什么隔离级别而已。它只是个传话的角色。

private ThreadLocal<Connection> connLocal = new ThreadLocal<Connection>(); spring通过线程本地变量来同享connection来实现多个dao方法的执行对数据库来说都源自同一个connection对象,自然就是同一次事务。只要任意方法抛出被声明的异常,只要任意方法调用connection.rollback();connection.setAutoCommit(true);即可实现回滚,而不是所有方法都调用rollback();

暂时先写到这,以后我发现我存在认知偏差,我也会第一时间修改博客。

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值