问题描述: 写主库开事务的情况下会导致时不时的将更新/插入操作写入到从库上, 导致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. Noip2017赛前的一些记录

    前言 已经退役整整五个月了....选考以后终于又摸上了键盘.... 但是码力已经大不如前了........ 距离比赛也就只有一星期了....那就胡乱的做一些题目吧QAQ 这里是一些根据算法分类的咋杂题 ...

  2. Tomcat、MySQL的安装与配置

    JAVA环境配置 下载安装jdk(Java Development Kit) 配置安装环境 右键计算机——>属性——>高级系统设置——>环境变量——>新建 变量名:  JAVA ...

  3. win10 nginx + django +flup 配置

    1 安装 Nginx 官网下载,直接点exe启动即可 2 安装django pip install django 注意 新建立项目时 python *****/django-admin.py star ...

  4. repeated-substring-pattern

    https://leetcode.com/problems/repeated-substring-pattern/ 下面这个方法,开始我觉得挺好.可惜还是超时了.后来我就加了一个剪枝策略,只有长度能够 ...

  5. iOS_7_scrollView大图缩放

    终于效果图: BeyondViewController.h // // BeyondViewController.h // 7_scrollView大图展示 // // Created by beyo ...

  6. 解决Eclipse中C++代码显示Symbol &#39;std&#39; could not be resolved的问题

    第一次在Eclipse中写C++代码,写了一个简单的hello world程序,还没有等我编译.就报出了各种错误,但是这么简单的代码.怎么可能这么多错误.于是没有理会.编译执行后,能够正常输出!!!H ...

  7. 关于提高沟通能力的书单zz

    上周推荐了一份关于提高写作能力的书单,这周,我们来聊聊沟通能力. 在现代社会,沟通能力变得越来越重要.人与人之间的社交渠道越来越丰富,工作中的协同合作也越来越普遍.我们要沟通的人越来越多,节奏越来越快 ...

  8. ComboBox在WPF中的绑定示例:绑定项、集合、转换,及其源代码

    示例1.Selector(基类) 的示例Controls/SelectionControl/SelectorDemo.xaml <Page x:Class="Windows10.Con ...

  9. linux socket详解

    1 linux socket编程的固定模式 server端,bind.listen.accept client端,connect client端和server端之间的一次通信: client端,wri ...

  10. BZOJ3627: [JLOI2014]路径规划

    BZOJ3627: [JLOI2014]路径规划 Description 相信大家都用过地图上的路径规划功能,只要输入起点终点就能找出一条最优路线.现在告诉你一张地图的信息,请你找出最优路径(即最短路 ...