Springboot项目配置JDBC事务管理器
起因:弃用spring事务管理器,自己配置事务管理器
因为业务需要,在项目中弃用了spring自带的事务管理器,自己配置了JDBC的事务管理来代替spring的事务管理器。
主要代码如下:
其中SpringBootApplication标签的exclude属性排除DataSourceTransactionManagerAutoConfiguration和HibernateJpaAutoConfiguration是因为这2个里边也有自带的事务管理,所以要去掉。
启动类
@SpringBootApplication(exclude={DataSourceTransactionManagerAutoConfiguration.class,HibernateJpaAutoConfiguration.class})//MybatisAutoConfiguration.class,
@EnableDiscoveryClient
@ComponentScan({"com.demo"})
public class DemoApplication
{
public static void main( String[] args )
{
SpringApplication.run(DemoApplication .class, args);
}
}
配置类
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
// 设置JDBC形式事务管理器↓
TransactionFactory tf = new JdbcTransactionFactory();
factory.setTransactionFactory(tf);
// 设置JDBC形式事务管理器↑
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
factory.setConfiguration(properties.getConfiguration());
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
return factory.getObject();
}
问题:使用自己开发的事务注解标签后,发现事务抛出异常时,无法回滚!
几番调查,确定了如下3点
①确实调用了sqlsession的rollback方法。
②数据表引擎确实是innodb。
③事务管理器确实配置了自动提交属性=false。
看上去,一切正常,but就是不能回滚。。。。。
偶然的机会,右手边的肉肉的小伙帮,发现项目debug启动时,在自动配置方法中打的断点,没有停!!!!!!!!!!!!
直接原因:事务管理器的自动配置类没有生效!
最开始,以为是配置类上的@ConditionalOnMissingBean标签导致,于是去掉该标签,甚至加上了@primary标签,都不行!!!!!
解决方法:万能的架构师
最后实在没招了,把问题抛出,给了我们伟大、牛逼的架构师大佬。只见大佬啪啪啪,几下键盘,手起键落,进了@SpringBootApplication标签的源码,返现这个标签里的有个属性scanBasePackages和@ComponentScan标签会引起冲突,导致配置类无法加载。于是把启动类上的@ComponentScan标签删除,改用@SpringBootApplication标签里的scanBasePackages属性,具体代码如下:
@SpringBootApplication(exclude={DataSourceTransactionManagerAutoConfiguration.class,HibernateJpaAutoConfiguration.class},scanBasePackages={"com.demo"})//MybatisAutoConfiguration.class,
@EnableDiscoveryClient
public class DemoApplication
{
public static void main( String[] args )
{
SpringApplication.run(DemoApplication .class, args);
}
}
到此,问题解决!
①向大佬致敬。
②看源码很重要,不能迷信这些牛逼的框架。