首页 > 其他分享 >关于mybatis-plus多数据源以及@Transactional使用的注意点

关于mybatis-plus多数据源以及@Transactional使用的注意点

时间:2022-12-04 01:44:09浏览次数:45  
标签:mapper return saveBatch 数据源 Transactional plus public

1. myatis-plus多数据源使用,我用的不是dymanic datasource,而是自定义的多数据源配置方式,如下图,相信很多人都用过,由于我不是介绍怎么使用多数据源,所以具体的我就不介绍了。

@Configuration
@MapperScan(basePackages = "com.lyten.custom.system.mapper", sqlSessionTemplateRef = "sysSqlSessionTemplate")
public class ConfigDataSource extends MybatisplusMultiConfig {
    @Autowired
    private ConfigDataSourceProperty configDataSourceProperty;

    @Bean(name = "sysds")
    public DataSource dataSource() {
        return super.dataSource(configDataSourceProperty);
    }

    public SqlSessionFactory sqlSessionFactory()
            throws Exception {
        DataSource ds = SpringUtils.getBean("sysds");
        return super.sqlSessionFactory(ds, configDataSourceProperty.getMapperLocations());
    }

    @DependsOn("sysds")
    @Bean(name = "sysSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
        return super.sqlSessionTemplate(sqlSessionFactory());
    }
    @Bean("sysTransactionManager")
    public PlatformTransactionManager sysTransactionManager(@Qualifier("sysds") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}

这里有个很要注意的地方,我是有多个模块,每个模块都有resources,resource目录下都有mapper目录,里面装着模块各自的xxxMapper.xml。三个模块的目录结构相同。例如A,B,C三个模块吧。当我从前端调A模块的插入方式时,会报表不存在,查看报错,我插入的是A.sysUser,但报错是插入了B.sysUser。我检查了数据源配置,@MapperScan扫描路径并没有错,怎么会插到别的用户下了呢?通过调试到baseMapper里,发现到了SqlHelper时,居然是B的数据源,并且statement也是乱的,B的statement把A的mapper也装进去了,在这里我才知道不是@MapperScan扫描mapper的问题,是扫描xml时出了问题,这问题就在于三个模块的xml路径完全一样,因此在yml中配置都是mapperLocations: classpath*:mapper/*Mapper.xml。后面,我把每个模块都改了下,例如A的xml在resources/system/mapper里,同时mapperLocations也改成了classpath*:system/mapper/*Mapper.xml,这样就解决了这个问题。

 

第二个问题,@Transactional使用的注意点,当然,我目前出问题,主要是saveBatch这个方法,像save、update方法都没有问题。主要是什么呢,还是同一个项目,有三个数据源,也有创建了三个TransactionManager的bean,在方法调用时,也明确声明了

@Override
@Transactional(rollbackFor = Exception.class,transactionManager = "sysTransactionManager")
    public boolean copy(String sourceSubId, String targetSubId, String userId) {
  // 
return saveBatch(sysCustomDicTemplateList); }

这个方法中间的查询什么的都没有问题,但执行saveBatch的时候,报了No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 3:,有三个TransactionManager,它不知道该用哪个。我查了saveBatch方法,如下,这是com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

    /**
     * 批量插入
     *
     * @param entityList ignore
     * @param batchSize  ignore
     * @return ignore
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
    }

 

 WHF?这里不也是@Transactional么?没有设置事务的传播类型,不是会加入已有事务么?怎么会报没事务呢?具体原因有点复杂,就是它这个方法在后面执行中,会去取默认的TransactionManager,而不是取我设置的那个,但是我程序中没有设置默认的TransactionManager,因此,它就会报这个错,解决办法有两个,一个是设置一个默认的TransactionManager,但不行,因为我有三个数据源。那第二个就是重写saveBatch方法了。

@Transactional(rollbackFor = Exception.class,transactionManager = "apisysTransactionManager")
    public boolean saveBatch(List<SysCustomDicTemplate> sysCustomDicTemplateList) {
        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
        return executeBatch(sysCustomDicTemplateList, sysCustomDicTemplateList.size(), (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
    }

 

两个问题其实解决都不复杂,就是发现这些问题,花了很长时间。

标签:mapper,return,saveBatch,数据源,Transactional,plus,public
From: https://www.cnblogs.com/lythen/p/16949284.html

相关文章