问题描述: 写主库开事务的情况下会导致时不时的将更新/插入操作写入到从库上, 导致mysqlException update command denied

 
问题原因: jetty的工作队列会重用处理线程, 导致threadLocal中的值被重用, 然而transaction注解在service层, 他会在DynamicDataSourceSwitch被设置之前直接去threadlocal拿数据, 本应拿到null, 但是拿到了之前线程的值
 
一般代码调用链:
Repository@Annotation(AOP)-->DefaultSqlSession-->SimpleExecutor-->BaseExecutor.getConnection()-->SpringManagedTransaction.getConnection()--->连接为空-->AbstractRoutingDataSource.getConnection()-->拿到beforeAOP中注入的datasource的key, 所以每次都会动态切换数据源
 
事务代码调用链:
service注解上@transactional-->TransactionInterceptor.interpter()-->TransactionAspectSupport.createTransactionIfNecessary()-->AbstractPlatformTransactionManager.getTransaction()-->DataSourceTransactionManager.doBegin()-->AbstractRoutingDataSource.determineTargetDataSource()[lookupKey==null去拿默认的Datasource, 不为空则使用获取到的连接]-->DataSourceTransactionManager.setTransactional()[将连接设置到TransactionUtils的threadLocal中]--->Repository@Annotation-->执行一般调用链, 问题在于SpringManagedTransaction.getConnection()-->openConnection()-->DataSourceUtils.getConnection()-->TransactionSynchronizationManager.getResource(dataSource)不为空[从TransactionUtils的threadLocal中获取数据源], 所以不会再去调用DynamicDataSource去获取数据源
 

有时间再补一个Sequence图

 
问题解决, DataSourceAdvice AfterReturn需要删除threadLocal中的数据源key 
 
public class DataSourceAdvice
implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice { private static final Logger LOG = LoggerFactory.getLogger(DataSourceAdvice.class); @Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
throws Throwable {
DataSourceSwitcher.clearDataSource();
} }

Transaction事务注解和DynamicDataSource动态数据源切换问题解决的更多相关文章

  1. Spring动态切换多数据源事务开启后,动态数据源切换失效解决方案

    关于某操作中开启事务后,动态切换数据源机制失效的问题,暂时想到一个取巧的方法,在Spring声明式事务配置中,可对不改变数据库数据的方法采用不支持事务的配置,如下: 对单纯查询数据的操作设置为不支持事 ...

  2. Java注解--实现动态数据源切换

    当一个项目中有多个数据源(也可以是主从库)的时候,我们可以利用注解在mapper接口上标注数据源,从而来实现多个数据源在运行时的动态切换. 实现原理 在Spring 2.0.1中引入了Abstract ...

  3. 【开发笔记】- AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换

    AbstractRoutingDataSource动态数据源切换 上周末,室友通宵达旦的敲代码处理他的多数据源的问题,搞的非常的紧张,也和我聊了聊天,大概的了解了他的业务的需求.一般的情况下我们都是使 ...

  4. Spring主从数据库的配置和动态数据源切换原理

    原文:https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000 在大型应用程序中,配 ...

  5. AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u012881904/article/de ...

  6. AbstractRoutingDataSource 实现动态数据源切换原理简单分析

    AbstractRoutingDataSource 实现动态数据源切换原理简单分析 写在前面,项目中用到了动态数据源切换,记录一下其运行机制. 代码展示 下面列出一些关键代码,后续分析会用到 数据配置 ...

  7. SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换

    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换 本文转载至:http://exceptioneye.iteye.com/blog/1698064 Spri ...

  8. SpringBoot学习笔记:动态数据源切换

    SpringBoot学习笔记:动态数据源切换 数据源 Java的javax.sql.DataSource接口提供了一种处理数据库连接的标准方法.通常,DataSource使用URL和一些凭据来建立数据 ...

  9. 30个类手写Spring核心原理之动态数据源切换(8)

    本文节选自<Spring 5核心原理> 阅读本文之前,请先阅读以下内容: 30个类手写Spring核心原理之自定义ORM(上)(6) 30个类手写Spring核心原理之自定义ORM(下)( ...

随机推荐

  1. java中正则表达式要进行转义的字符。

    /** * 转义正则特殊字符 ($()*+.[]?\^{},|) * * @param keyword * @return */public static String escapeExprSpeci ...

  2. Java heap space设置方法记录

    最近被 OutOfMemory Error折腾得够呛,记载一点设置JVM虚拟机内存Javaheap space的方法. Tomcat 7 参考:  http://www.davidghedini.co ...

  3. Maven添加坐标(依赖)及在Eclipse中的操作

    例如:添加一个spring-test.jar的依赖过程,普遍的做法就是直接操作pom.xml文件. 1.打开maven的中央仓库:http://search.maven.org/ 2.搜索仓库: 进入 ...

  4. javascript --- 临时构造器F()

    这篇内容也是之前讲到过的,纯属无聊,莫要见怪.~(- ̄▽ ̄)-~(- ̄▽ ̄)-~(- ̄▽ ̄)-~(- ̄▽ ̄)-~(- ̄▽ ̄)- 正如上文所说,如果所有的prototype属性都指向了一个相同的对象,父 ...

  5. Android动画中Interpolator 详解和演示

    遇到一个项目需求,想让动画变得更活泼一点,于是想到了动画属性中的Interpolator,写了基本例子测试一下Android提供给我们现成的加速器的效果: 效果 代码中方法 xml中属性 越来越快 A ...

  6. 为什么HierachyViewer无法连接真机调试

    关于什么是Hierarchy Viewer,请查看官方文档:http://developer.android.com/tools/debugging/debugging-ui.html.个人理解:Hi ...

  7. win10安装 迅雷

    下载安装文件所在目录 ,右键,选择以管理员身份运行,输入程序地址,如D:\download\ThunderMini_dl1.5.3.288.exe,回车,这样就出来了程序安装页面,之后就可以就行正常的 ...

  8. ssh登录时不校验被登录机器的方法

    在linux的用户目录下的.ssh文件下,touch config:注意config的权限控制,-rw-r--r--. 配置内容: cat config: Host * StrictHostKeyCh ...

  9. php-fpm.conf配置说明(重点要改动和优化的地方)

    <?xml version="1.0" ?> <configuration> All relative paths in this config are r ...

  10. Lightoj 1088 - Points in Segments 【二分】

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1088 题意: 有一维的n个点和q条线段.询问每条线段上的点有多少个. 思路:寻 ...