多数据源导致事务不生效

@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;
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值