• SpringBoot + Mybatis 多数据源切换无法进行 写数据库 操作记录


      使用注解 + AOP代理的方式对业务包方法的标记,配置继承AbstractRoutingDataSource类实现对于数据源的切换.
    测试时, 可以进行查询,但不能进行更新插入等写数据库操作。
    使用@order() 默认值为2147483647,对切换数据源的注解和开启事务注解进行标注, 测试失败。
    应用启动时使用了@EnableTransactionManagement() 开启了事务管理。

      用AOP切换数据源,AOP的切点必须在事务开启之前切换,否则无效,因为spring一旦使用事务获取连接,
    则会在事务开启后获取到连接,后面的都是放入当前线程中,即事务内所用的连接都是同一个,此时是无法改变的,
    必须要在事务开启前切换好数据源才能达到目的。

      解决方法:编写事务配置类,配置事务管理器
    PlatformTransactionManager定义相关业务接口和实现类新的事务传播行为。
    (传播行为定义了被调用方法的事务边界) REQUIRES_NEW(),配置自定义的事务拦截器,将服务接口及实现类配置进去。

    • PlatformTransactionManager
    package org.springframework.transaction;
    
    import org.springframework.lang.Nullable;
    
    public interface PlatformTransactionManager {
        //事务状态
        TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
        //提交事务
        void commit(TransactionStatus var1) throws TransactionException;
        //回滚事务
        void rollback(TransactionStatus var1) throws TransactionException;
    }
    
    
    • 配置事务管理器
    
    
    @Bean(CUSTOMIZE_TRANSACTION_INTERCEPTOR_NAME)
        public TransactionInterceptor customizeTransactionInterceptor(PlatformTransactionManager transactionManager) {
            NameMatchTransactionAttributeSource transactionAttributeSource = new NameMatchTransactionAttributeSource();
            RuleBasedTransactionAttribute readOnly = this.readOnlyTransactionRule();
            RuleBasedTransactionAttribute required = this.requiredTransactionRule();
            // 默认的只读事务配置
            for (String methodName : DEFAULT_READ_ONLY_METHOD_RULE_TRANSACTION_ATTRIBUTES) {
                transactionAttributeSource.addTransactionalMethod(methodName, readOnly);
            }
            // 默认的传播事务配置
            for (String methodName : DEFAULT_REQUIRED_METHOD_RULE_TRANSACTION_ATTRIBUTES) {
                transactionAttributeSource.addTransactionalMethod(methodName, required);
            }
            // 定制的只读事务配置
            for (String methodName : customizeReadOnlyMethodRuleTransactionAttributes) {
                transactionAttributeSource.addTransactionalMethod(methodName, readOnly);
            }
            // 定制的传播事务配置
            for (String methodName : customizeRequiredMethodRuleTransactionAttributes) {
                transactionAttributeSource.addTransactionalMethod(methodName, required);
            }
            return new TransactionInterceptor(transactionManager, transactionAttributeSource);
        }
    
    
    
    • 配置拦截器
    @Bean
        public BeanNameAutoProxyCreator customizeTransactionBeanNameAutoProxyCreator() {
            BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
            // 设置定制的事务拦截器
            beanNameAutoProxyCreator.setInterceptorNames(CUSTOMIZE_TRANSACTION_INTERCEPTOR_NAME);
            // 默认
            for ( String defaultTransactionBeanNameSuffix : DEFAULT_TRANSACTION_BEAN_NAMES ) {
                beanNameAutoProxyCreator.setBeanNames( defaultTransactionBeanNameSuffix );
            }
            // 定制
            for (String customizeTransactionBeanName : customizeTransactionBeanNames) {
                beanNameAutoProxyCreator.setBeanNames(customizeTransactionBeanName);
            }
            beanNameAutoProxyCreator.setProxyTargetClass(true);
            return beanNameAutoProxyCreator;
        }
    • 传播行为

    ( 传播行为定义了被调用方法的事务边界 )

    传播行为       propagation                             意义                          
    PROPAGATION_REQUIRED 方法必须运行在一个事务内,如果当前存在一个事务,那么该方法运行在这个事务中,否则,将创建一个新的事务。
    REQUIRES_NEW 创建一个新的事务,如果存在当前事务的话,暂停(挂起)当前事务 。
    SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
    NOT_SUPPORTED 不执行当前事务;总是执行非事务。
    MANDATORY 支持当前事务;如果当前事务不存在则抛出一个异常。
    NESTED 如果当前存在事务的话,执行一个嵌套的事务,不存在创建新的。
    NEVER 不支持当前事务;如果存在当前事务则抛出一个异常



      
  • 相关阅读:
    1022-哈夫曼编码与译码
    openresty 学习笔记二:获取请求数据
    openresty 学习笔记一:环境安装
    Lua在Windows下的安装、配置、运行
    Django框架中logging的使用
    死磕nginx系列--使用upsync模块实现负载均衡
    死磕nginx系列--nginx 限流配置
    死磕nginx系列--使用nginx做cache服务
    死磕nginx系列--使用nginx做负载均衡
    死磕nginx系列--nginx服务器做web服务器
  • 原文地址:https://www.cnblogs.com/JMrLi/p/11856131.html
Copyright © 2020-2023  润新知