springboot事务相关
1. 开启全局事务支持
SpringbootApplication中 启用配置@EnableTransactionManagement, 用来支持@Transactional
开启APO配置支持@EnableAspectJAutoProxy (exposeProxy = true) 用来支持aop方式的自动事务配置
其中 exposePorxy默认false, 设为true,才可使用AopContext.currentProxy()获取TreadLocal中当前类的代理实例
2. 新建测试类及接口
总结
spring.datasource.druid.default-auto-commit = true 或 false 对事务执行无影响,可以不用配置, 事务生启的时候会将connection.autocommit=false
B.b1 -> A.save 事务有效
B.b1 -> A.a1 -> this.save 时,事务无效
原因: a1方法中调用本地的save时,未通过proxy代理走 生效事务: a1 -> AopContext.currentProxy().save()
2.1 配置类
execution(* org.arrow.service.TestService.*(..)) save* 配置 REQUIRED 事务
2.2 业务接口相关方法
public void saveTest1() {
for (int i = 0; i < 3; i++) {
Test1 test1 = new Test1();
test1.setSeq("test1_" + i);
test1Mapper.insertSelective(test1);
}
}
public void saveTest2() {
for (int i = 0; i < 2; i++) {
Test2 test2 = new Test2();
test2.setSeq("test2_" + i);
test2Mapper.insertSelective(test2);
}
}
public void abcdAll() {
// 不会开启事务
saveTest2();
// 开启事务
proxy = AopContext.currentProxy();
proxy.saveTest1();
}
3.3 测试类
@Test
public void test(){
testService.abcdAll();
}
4. mybatis中事务配置全量
关键点
事务配置线 datasource -> TransactionManager(ds) -> txAdvice(txmanager) -> txAdvisor(txAdvice)
mybatis配置线 datasource -> sqlSessionFactoryBean(ds) -> mapperScannerConfigurer(sessionFactory)
rollbackFor的配置,默认为RuntimeException.class, 可以设置为Exception.class 相关代码
// 数据源
@Bean(name = "dataSource")
@ConfigurationProperties("spring.datasource.druid")
public DataSource dataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("org.arrow.shop.bean");
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mybatis/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer cfg = new MapperScannerConfigurer();
cfg.setBasePackage("org.arrow.*.dao");
cfg.setSqlSessionFactoryBeanName("sqlSessionFactory");
return cfg;
}
@Bean("txManager")
public PlatformTransactionManager annotationDrivenTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
private static final int TX_METHOD_TIMEOUT = 50000;
private static final String AOP_POINTCUT_EXPRESSION = "execution(* org.arrow.shop.service.TestService.*(..))";
// 事务的实现Advice
@Bean
public TransactionInterceptor txAdvice(@Qualifier("txManager")PlatformTransactionManager m) {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
requiredTx.setTimeout(TX_METHOD_TIMEOUT);
Map txMap = new HashMap<>();
txMap.put("add*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("delete*", requiredTx);
txMap.put("get*", readOnlyTx);
txMap.put("query*", readOnlyTx);
source.setNameMap(txMap);
TransactionInterceptor txAdvice = new TransactionInterceptor(m, source);
return txAdvice;
}
// 切面的定义,pointcut及advice
@Bean
public Advisor txAdviceAdvisor(@Qualifier("txAdvice") TransactionInterceptor txAdvice) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
5. mysql中事务的设置 (无用)
检查mysql中事务设置,springboot的事务与mysql默认事务策略无关
show variables like 'autocommit';
> autocommit ON
关闭自动事务
set autocommit = 0;
关闭全局autocommit
set @@global.autocommit=0;