springboot下事務配置相關(druid及mybatis)


springboot事務相關

1. 開啟全局事務支持

  • SpringbootApplication中 啟用配置@EnableTransactionManagement, 用來支持@Transactional
  • 開啟APO配置支持@EnableAspectJAutoProxy (exposeProxy = true) 用來支持aop方式的自動事務配置

其中 exposePorxy默認false, 設為true,才可使用AopContext.currentProxy()獲取TreadLocal中當前類的代理實例

2. 新建測試類及接口

總結

  • spring.datasource.druid.default-auto-commit = truefalse 對事務執行無影響,可以不用配置, 事務生啟的時候會將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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM