Spring Transaction 指定事务管理器问题

一,单个数据源,单个事务管理器与@Transactional默认事务管理器名称不一致问题

在平时代码中使用声明性事务时,直接在方法上面加注解即可,如下

@Transactional(rollbackFor = Exception.class)

并没有指定事务管理器,为什么?

因为只有一个数据源,只有一个事物管理器。多数据源,多个事物管理器时才需要指定事务管理器

如下创建事物管理器

@Bean(name = "defaultTransactionManager")
@Primary
public DataSourceTransactionManager defaultDataSourceTransactionManager(
        @Qualifier("defaultDataSource") DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

但是创建的事物管理器名称是 defaultTransactionManager 

@Transactional 注解中默认的事物器管理器是 transactionManager

为什么依然有效 

参考文章

千云物流- 多数据源事务管理_多数据源datasourcetransactionmanager-CSDN博客

SpringBoot手动开启事务:DataSourceTransactionManager-CSDN博客

【老王读Spring Transaction-7】一个数据源的事物管理配置 与 多数据源的事物管理配置_springboot 配置 @transactional 的数据源-CSDN博客

二,相关知识点

1,@Transactional注解不生效问题

常见情况:

1,方法内部调用:

一个类中,A方法调用加了事物注解的B方法;或A事物方法调用B事物方法,B事物依然不会生效

2,方法不是public

3,多数据源情况,事物管理器没有指定正确

4,@Transactional 注解属性 rollbackFor 设置错误

5,异常被catch了

6,自调用:事物方法A,内部调用的类中无事物方法B,如果B抛出异常,A方法其他内容不回滚

Spring @Transactional注解失效的情况及解决方法_@transactional注解不生效-CSDN博客

针对第六点方案有疑问

2,编程性事物 

为了解决大事物问题

3,SqlSessionFactory 创建

包含:如果是mybatisplus如何配置,如何指定xml路基

@Configuration
@MapperScan(basePackages = {"com.*","com.*"}, sqlSessionFactoryRef = "mallSqlSessionFactory")
public class DataBaseConfig {

    private static final Logger logger = LoggerFactory.getLogger(Constant.LOGGER);

    @Value("${spring.datasource.mall.druid.filters:stat}")
    private String filter;

    @Value("${spring.datasource.mall.druid.maxActive:20}")
    private int maxActive;

    @Value("${spring.datasource.mall.druid.minIdle:5}")
    private int minIdle;

    @Value("${spring.datasource.mall.druid.initialSize:5}")
    private int initialSize;

    @Value("${spring.datasource.mall.druid.maxWait:90000}")
    private int maxWait;

    @Value("${spring.datasource.mall.druid.timeBetweenEvictionRunsMillis:60000}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.mall.druid.minEvictableIdleTimeMillis:3000000}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.mall.druid.poolPreparedStatements:false}")
    private boolean poolPreparedStatements ;

    @Bean(name = "mallDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mall")
    public DataSource mallDataSource() {
        //指定使用DruidDataSource
        DruidDataSource dataSource = (DruidDataSource) DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
        try {
            dataSource.setInitialSize(initialSize);
            dataSource.setMinIdle(minIdle);
            dataSource.setMaxActive(maxActive);
            dataSource.setMaxWait(maxWait);
            dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            dataSource.setPoolPreparedStatements(poolPreparedStatements);
            dataSource.setFilters(filter);
            logger.info("初始化mallDataSource Druid监控配置成功");
        }catch (Exception e){
            logger.warn("初始化Druid监控配置失败");
        }
        return dataSource;
    }

    @Bean(name = "mallSqlSessionFactory")
    public SqlSessionFactory mallSqlSessionFactory(@Qualifier("mallDataSource") DataSource dataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        Interceptor[] plugins =  new Interceptor[]{new PageHelper()};
        bean.setPlugins(plugins);
        List<String> mapperLocations = new ArrayList<>();
        mapperLocations.add("classpath:mybatis/mappers/customer/*.xml");
        mapperLocations.add("classpath:mybatis/mappers/community/*.xml");
        Resource[] resources = resolveMapperLocations(mapperLocations);
        bean.setMapperLocations(resources);
        return bean.getObject();
    }

    @Bean(name = "mallTransactionManager")
    public PlatformTransactionManager mallTransactionManager(@Qualifier("mallDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "mallSqlSessionTemplate")
    public SqlSessionTemplate mallSqlSessionTemplate(
            @Qualifier("mallSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 指定多路径
     */
    private Resource[] resolveMapperLocations(List<String> mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return resources.toArray(new Resource[0]);
    }
}

   @Bean(name = "defaultSqlSessionFactory")
    @Primary
    public SqlSessionFactory defaultSqlSessionFactory(@Qualifier("defaultDataSource") DataSource dataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        Interceptor[] plugins = {paginationInterceptor};
        bean.setPlugins(plugins);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/*.xml"));

        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setMetaObjectHandler(new MyMetaObjectHandler());
        bean.setGlobalConfig(globalConfig);
        return bean.getObject();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值