一,单个数据源,单个事务管理器与@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();
}