1.前言
在前面的文章中,提到一种手动提交多数据源事务的实现方式,dynamic-datasource包为我们提供了一种更为优雅,开箱即用的注解,即@DSTransactional,因为spring提供的@Tansactional注解是不支持多数据源的,@DSTransactional注解的出现刚好可以很好的弥补这一点。@DS注解和@DSTransactional注解是可以同时使用的,并且两者也是有着密不可分的联系,关于@DS注解请看我上一篇文章分析:动态数据源切换——@DS注解源码解析
2.@DSTransactional注解原理
1)在前文@DS注解的讨论中,不难发现DynamicDataSourceAopConfiguration
类中还注册了一个advisor,就是@DSTransactional注解的切面:
2)再看DynamicLocalTransactionInterceptor
类,具体的事务开启和执行提交回滚放到了LocalTxUtil
类中
3)跟随LocalTxUtil
类,将xid存入ThreadLocal类型的holder中实现开启本地事务,在拦截器的invoke
方法中也会校验holder中是否为空,如果已经存在事务id,就直接执行目标方法;
4)TransactionContext
类:
5)提交和回滚由ConnectionFactory
类实现:ConnectionFactory中定义了CONNECTION_HOLDER
存放数据源名称和ConnectionProxy
的对应关系,而ConnectionProxy
才是真正实现提交和回滚的类。
而putConnection方法是在执行AbstractRoutingDataSource#getConnection
时被调用:
6)ConnectionProxy
是Connection
接口的实现类,ConnectionProxy
的成员变量很简单只有数据源名称和Connection对象,要做的事情也很简单就是提交和回滚,在其实现上用notify方法代替,并没有实现Connection类的commit、rollback;默认设置提交方式为手动提交
3.总结
根据前文的分析,在执行AbstractRoutingDataSource#getConnection
时,如果没有将数据源加入到ConnectionFactory
,则会先切换数据源,再创建ConnectionProxy
并将其加入ConnectionFactory
:
在开启多数据源事务时,先判断是否存在本地事务,是的话加入,即直接执行目标方法(就是传播行为的REQUIRED),随后方法执行完成后,根据是否有异常将所有加入到ConnectionFactory
的连接一起提交或回滚:
本博客内容仅供个人学习使用,禁止用于商业用途。转载需注明出处并链接至原文。
标签:回滚,ConnectionProxy,数据源,DSTransactional,提交,注解 From: https://www.cnblogs.com/zhaobo1997/p/17976348