zoukankan      html  css  js  c++  java
  • Transaction事务注解和DynamicDataSource动态数据源切换问题解决

    问题描述: 写主库开事务的情况下会导致时不时的将更新/插入操作写入到从库上, 导致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();
    }
    
    }
  • 相关阅读:
    java int转byte数组
    业务网关-操作手册
    业务网关-配置
    H2数据库的导入、导出(CSV)
    sequelize踩坑处理:时间格式化
    引入koa-static处理静态资源
    MySql利用case when实现批量更新多条记录的不同值实现方法
    Sequelize增删改查及批量新增或批量更新(bulkCreate的updateOnDuplicate)等常用接口
    数据结构队列、双端队列、队列系算法题解析
    配置webpack中externals来减少打包后vendor.js的体积
  • 原文地址:https://www.cnblogs.com/zhwbqd/p/3757060.html
Copyright © 2011-2022 走看看