zoukankan      html  css  js  c++  java
  • 多数据源导致事务不生效

        @Autowired
        @Qualifier("writeDataSource")
        private DataSource writeDataSource;
    
        @Bean("txManager")
        public DataSourceTransactionManager txManager(@Qualifier("roundRobinDataSouceProxy") DataSource roundRobinDataSouceProxy) {
            return new DataSourceTransactionManager(roundRobinDataSouceProxy);
        }
    

    读写路由

        /**
         * 把所有数据库都放在路由中
         *
         * @return
         */
        @Bean(name = "roundRobinDataSouceProxy")
        public AbstractRoutingDataSource roundRobinDataSouceProxy() {
    
            Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
            //把所有数据库都放在targetDataSources中,注意key值要和determineCurrentLookupKey()中代码写的一至,
            //否则切换数据源时找不到正确的数据源
            targetDataSources.put(DataSourceType.write.getType(), writeDataSource);
            targetDataSources.put(DataSourceType.read.getType(), readDataSource);
    
            //路由类,寻找对应的数据源
            AbstractRoutingDataSource proxy = new AbstractRoutingDataSource() {
                /**
                 * 这是AbstractRoutingDataSource类中的一个抽象方法,
                 * 而它的返回值是你所要用的数据源dataSource的key值,有了这个key值,
                 * targetDataSources就从中取出对应的DataSource,如果找不到,就用配置默认的数据源。
                 */
                @Override
                protected Object determineCurrentLookupKey() {
                    String typeKey = DataSourceContextHolder.getReadOrWrite();
    
                    if (typeKey == null) {
                        System.err.println("使用数据库write.............");
                        return DataSourceType.write.getType();
                    }
    
                    if (typeKey.equals(DataSourceType.write.getType())) {
                        System.err.println("使用数据库write.............");
                        return DataSourceType.write.getType();
                    }
    
                    //读库, 简单负载均衡
                    System.err.println("使用数据库read");
                    return DataSourceType.read.getType();
                }
            };
            //默认库
            proxy.setDefaultTargetDataSource(writeDataSource);
            proxy.setTargetDataSources(targetDataSources);
            return proxy;
        }
    
    
    /**
     * 在service层觉得数据源
     * 
     * 必须在事务AOP之前执行,所以实现Ordered,order的值越小,越先执行
     * 如果一旦开始切换到写库,则之后的读都会走写库
     * 
     */
    @Aspect
    @EnableAspectJAutoProxy(exposeProxy=true,proxyTargetClass=true)
    @Component
    public class DataSourceAopInService implements PriorityOrdered{
    
    //private static Logger log = LoggerFactory.getLogger(DataSourceAopInService.class);
    	
    @Before("execution(* net.vipmro.hades.boss.service..*.find*(..)) "
    		+ " or execution(* net.vipmro.hades.boss..*.get*(..)) "
    		+ " or execution(* net.vipmro.hades.boss..*.select*(..)) "
    		+ " or execution(* net.vipmro.hades.boss..*.search*(..)) "
    
    		+ " or execution(* net.vipmro.hades.boss..*.query*(..))")
    	public void setReadDataSourceType() {
    		//如果已经开启写事务了,那之后的所有读都从写库读
    		if(!DataSourceType.write.getType().equals(DataSourceContextHolder.getReadOrWrite())){
    			DataSourceContextHolder.setRead();
    		}
    	    
    	}
    	
    @Before("execution(* net.vipmro.hades.boss..*.insert*(..)) "
    		+ " or execution(* net.vipmro.hades.boss..*.update*(..))"
    		+ " or execution(* net.vipmro.hades.boss..*.save*(..))"
    		+ " or execution(* net.vipmro.hades.boss..*.del*(..))"
    		+ " or execution(* net.vipmro.hades.boss..*.add*(..))")
    	public void setWriteDataSourceType() {
    	    DataSourceContextHolder.setWrite();
    	}
        
    	@Override
    	public int getOrder() {
    		/**
    		 * 值越小,越优先执行
    		 * 要优于事务的执行
    		 * 在启动类中加上了@EnableTransactionManagement(order = 10) 
    		 */
    		return 1;
    	}
    
    }
    
    
  • 相关阅读:
    torch上疑问用法总结
    matplotlib库介绍
    java学习总结
    java高级并发编程实战
    java的spi思想--打破双亲委派模型的操作
    linux设置静态ip步骤流程
    jvm调优参数设置
    jvisualvm插件的基本使用
    jvm常见的gc种类
    jvm调优案例与步骤
  • 原文地址:https://www.cnblogs.com/liuyupen/p/15407005.html
Copyright © 2011-2022 走看看