场景一:
假设A方法调用B方法,A方法上面是@Transactional注解,B方法上面有GlobalTransactional事务注解,那么在执行B方法的时候会开启全局事务,生成xid保存到ThreadLocal中,在方法A执行完的时候,在提交事务的时候,Connection类型是seata的ConnectionProxy对象【为什么是这个,下面会介绍】,会判断是否存在全局事务,如果存在,会执行全局事务的那一套逻辑,但是B方法执行完的时候全局事务已经提交了,所以在进行注册分支的时候就出错。
解决方法:在A方法上面也加上全局事务注解。
为什么Connection类型是seata的ConnectionProxy对象?
SeataAutoDataSourceProxyCreator会将DataSource生成代理对象,当调用DataSource的方法的时候会调用到SeataAutoDataSourceProxyAdvice方法中去,该方法返回的是一个代理对象。

在A方法调用B方法的场景中,A使用了@Transactional,B使用了GlobalTransactional。由于Seata的机制,B方法执行时开启全局事务,但在A方法结束提交时,B的全局事务已提交,导致注册分支事务失败。解决方法是在A方法上也添加全局事务注解。Seata通过自动代理DataSource创建ConnectionProxy,以实现事务管理功能。
2万+

被折叠的 条评论
为什么被折叠?



