背景:数据库数据迁移
情况:事务中使用了多张表,一次只切换其中一张或几张
方式1:去除事务 - 根据业务情况定
方式2:核心事务中的表一起切
方式3:切换的几张不使用事务,其他走事务
方式3有多种解决方案
1.多线程、线程池 - 事务框架中,数据源使用的是线程的设置好的,中间切换数据源不管用
2.@Transactional(propagation = Propagation.NOT_SUPPORTED) - 看工程走的是JDK的动态代理还是cglib动态代理,JDK动态代理需要创建接口,cglib动态代理不需要;调用时要通过实例走代理调用;添加Propagation.NOT_SUPPORTED的事务传播类型的事务注解,标识当前方法不走事务
3.google的订阅发布 - 实际上也是多线程
试验后的总结
同类中调用
1.事务内调用私有方法,可整体回滚,同数据源 2.事务内调用私有方法多线程 new Thread的方式 - 同数据源 -- 事务不生效 3.事务内调用私有方法多线程 new Thread的方式 ,同步调用,不同数据源,事务内切换数据源失败,所以报异常,事务回滚 4. 事务内调用私有方法多线程 new Thread的方式,不同数据源,切数据源成功,异常不会滚 5.事务内调用私有方法多线程 线程池的方式,不同数据源,切数据源成功,异常不会滚 6.事务内调用私有方法多线程 公共线程池的方式,不同数据源,切数据源成功,异常不会滚 其他类走代理调用
1.不加事务的前提下,同数据源,可回滚
2.不加事务的前提下,不同数据源,数据源切换失败
3.加事务-propagation.NOT_SUPPORTED 可切换数据源,外部事务可回滚,内部不回滚
代码就不贴了很好写,记录