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<String, TransactionAttribute> 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;