Spring主从数据库切换,事务失效

2018-05-31  本文已影响96人  MC_Honva
前言

多数据库切换时候,存在事务,导致数据库切换失败,读写分离无法完成。其原因在于DataSourceTransactionManager类中,事务处理的方式,摘取部分源码,如下:

@Override
    protected void doBegin(Object transaction, TransactionDefinition definition) {
        .......
            // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
            // so we don't want to do it unnecessarily (for example if we've explicitly
            // configured the connection pool to set it already).
            if (con.getAutoCommit()) {
                txObject.setMustRestoreAutoCommit(true);
                if (logger.isDebugEnabled()) {
                    logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
                }
                con.setAutoCommit(false);
            }
            txObject.getConnectionHolder().setTransactionActive(true);
       .......
    }

因为建立数据源链接在一些连接驱动中是非常耗时的处理,所以为了避免这样的操作,在事务处理的时候,会先把数据源放入缓存中,等待事务处理完成才会清除缓存,所以如果在service层中的方法中添加了事务,并且方法中存在切换数据源的操作,将会导致切换失败。情景如下:

@Transactional
public Integer updateType(TypeDto typeDto) {
        ....
        TypeModle oldTypeModle = typeDao.findById(typeDto.getId());
        ....
        return this.enumTypeDao.updateById(oldtypeModle);
    }
解决方法及思路
//Service层
@Before("execution(* cn.ymanager.service..*.*(..))")
    public void dbAspect(JoinPoint point){
        .....
    }
//DAO层
@Transactional
public interface Dao extends BaseDao<Modle, Long> {
    ...........    
}
public class SpayTransactionManager extends DataSourceTransactionManager {

    @Override
    protected void doBegin(Object transaction, TransactionDefinition definition) {
        ...
        //写入自己的逻辑判断,并且切换到自己想到数据库
        super.doBegin(transaction, definition);
    }
}

关于主从数据库切换可参考此篇文章
SpringMVC主从数据库切换

上一篇下一篇

猜你喜欢

热点阅读