Spring boot transaction related (druid+mybatis)

Keywords: Mybatis MySQL SpringBoot Spring

springboot transaction related

1. Enable global transaction support

  • Enable @ EnableTransactionManagement in SpringbootApplication to support @Transactional
  • Enable APO configuration support @ EnableAspectJAutoProxy (exposeProxy = true) to support automatic transaction configuration in aop mode

Where exposePorxy defaults to false and is set to true, then AopContext.currentProxy() can be used to get the proxy instance of the current class in TreadLocal

2. New test class and interface

summary

  • spring.datasource.druid.default-auto-commit = true or false has no effect on transaction execution. Configuration is not required. connection.autocommit=false will be set when transaction is generated

  • B. B1 - > a.save transaction is valid

  • B. Invalid transaction when B1 - > a.a1 - > this.save

    Cause: when the local save was invoked in the a1 method, it did not go through the proxy proxy. Effective transaction: A1 - > aopcontext. Currentproxy(). Save()

2.1 configuration

execution(* org.arrow.service.TestService.*(..)) save* To configure REQUIRED affair

2.2 business interface related methods

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() {
    // Transaction will not be opened
    saveTest2();
    // Open transaction
    proxy =  AopContext.currentProxy();
    proxy.saveTest1();
}

3.3 test

@Test
public void test(){
    testService.abcdAll();
}

4. Total transaction configuration in mybatis

Key points

  • Transaction configuration line datasource -> TransactionManager(ds) -> txAdvice(txmanager) -> txAdvisor(txAdvice)
  • mybatis configuration line datasource -> sqlSessionFactoryBean(ds) -> mapperScannerConfigurer(sessionFactory)
  • The configuration of rollbackFor is RuntimeException.class by default, which can be set to Exception.class Related code
// data source
@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.*(..))";

// Implementation of transaction 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;
}

// Definition of section, pointcut and advice
@Bean
public Advisor txAdviceAdvisor(@Qualifier("txAdvice") TransactionInterceptor txAdvice) {
    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
    return new DefaultPointcutAdvisor(pointcut, txAdvice);
}

5. Transaction settings in MySQL (useless)

Check the transaction settings in mysql. The transaction of springboot is independent of the default transaction policy of mysql

 show variables like 'autocommit';
> autocommit    ON

Turn off automatic transactions
set autocommit = 0;
Turn off global autocommit
set @@global.autocommit=0;

Posted by vipul73 on Tue, 31 Mar 2020 21:32:20 -0700