SpringBoot @Transactional transaction control in the principle and troubleshooting invalid Affairs

Disclaimer: This article is a blogger hanchao5272 original articles, please indicate the source and leave the original link address, thank you! https://blog.csdn.net/hanchao5272/article/details/90343882

1.spring transaction management brief

Two transaction management:

  • Encoded transaction management: transaction control code written in the business code.
  • Declarative transaction management: based on AOP (Aspect Oriented Programming), transaction management and business logic decoupling. Two kinds of declarative transaction management implementation:
    • Configured in the configuration file (xml) in.
    • Based @Transactional annotation.

2.SpringBoot annotation in the @Transactional

2.1. Turn Affairs notes

On the project's main class, add comments @EnableTransactionManagement, such as:

@EnableTransactionManagement
public class MySpringBootService extends WebMvcConfigurerAdapter {
    public static void main(String[] args) {
        SpringApplication.run(CoreService.class, args);
    }
}

2.2. @Transactional add annotations on the target class, method

  1. If you add @Transactional to the class, then all of these methods are open transaction management. Such as:
   @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
   @Service
   public class MyServiceImpl implements MyService {
     //class body
   }
  1. If you add @Transactional to the method, then this method open transaction management. Such as:
       @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
       @Override
       public ActivityPo getActivityById(Long id){
         //method body
       }
  1. If there is a @Transactional method, and there are also @Transactional its own class, method level transaction configuration places subject.

2.3. Refinement transaction configuration

About @Transactional configurable parameters are many, there are propagation, rollbackForand so on, can be applied to different scenarios, here not elaborate.

3. @ Transactional Services Implementation Mechanism

3.1 overall transaction control process

  1. When @Transactional注解的方法the time is outside the class code calls, Spring class at runtime to generate a method for the location AOP代理对象.
  2. 代理对象According to property @Transactional deciding whether a 事务拦截器TransactionInterceptortransaction to intercept this method.
  3. During the transaction interception, will first open transaction, and then execute the business code, is abnormal according to the execution, by 抽象事务管理器AbstractPlatformTransactionManagerconduct or commit to rollback.

3.2.Spring AOP two agents

Spring AOP, there are two CglibAopProxyand JdkDynamicAopProxyin which:

  1. CglibAopProxyInside the class DynamicAdvisedInterceptorthe intercept()method, it is determined whether the transaction interception.

  2. JdkDynamicAopProxyIn its invoke()approach, to determine whether the transaction interception.

3.3. Underlying transaction operations implemented

  1. 抽象事务管理器AbstractPlatformTransactionManagerThe rollback and commit a specific category needs to be achieved.

  2. 抽象事务管理器AbstractPlatformTransactionManagerParent interfaces are PlatformTransactionManager.

  3. There are many transaction manager implementation class, for example, DataSourceTransactionManagerand so on.

  4. Different management resources to manage transaction data DataSource, such as DataSourceTransactionManagermanagement JDBCdata sources.

  5. It should ensure that the data source is used to call methods are loaded 事务管理器.

4. @ Transactional use of annotations and troubleshooting

4.1 database engine supports transactions?

  • MySql MyIsam engine does not support transactions.
  • For transaction control in effect, the database engine and tables must be InnoDB.

4.3. Where the class notes are loaded into whether Bean?

  • Section 3.1 article 1 mentioned need to generate a proxy object classes at runtime. So the premise is this class must be managed and loaded into a Spring Bean object.
  • Where the class is to be sure that @Component, @Service, @Controlleretc. notes notes.

4.2. Whether public comment method where modified?

  • Section 3.2, respectively, in reference to these two AOP agents intercept()and invoke()methods for determining whether a transaction interception.
  • Both methods called indirectly AbstractFallbackTransactionAttributeSourceclass computeTransactionAttributemethod to obtain the relevant property transaction control. Among these are the following piece of code:
	/**
	 * Same signature as {@link #getTransactionAttribute}, but doesn't cache the result.
	 * {@link #getTransactionAttribute} is effectively a caching decorator for this method.
	 * <p>As of 4.1.8, this method can be overridden.
	 * @since 4.1.8
	 * @see #getTransactionAttribute
	 */
	protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
		// Don't allow no-public methods as required.
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}
    
    //...
  }
  • This code will lead to no-publicmethods can not enter the transaction control.

  • Therefore, we must ensure that the method of transaction control they need to be included publicmodifier.

4.5. Whether the call from a problem?

  • Article 1, Section 3.1 stressed: only when the transaction method is called code outside the current class, it will be managed by a proxy object generated by Spring.

  • Since the above logic will cause problems call: When the transaction method is called internal method of this class, @ Transactional does not take effect.

  • Since calling the sample code:

    @Service
    public class PersonServiceImpl implements PersonService{
      @Resource
      private PersonDao personDao;
      
      public void insertPerson(Person person){
        //自调用
        personService.insert(person);
        
        //其他代码
        personDao.insertLog...
    	}
      
      @Transactional(rollbackFor = Exception.class)
      public void insert(Person person){
        personDao.insert(person);
    	}
    }
    
  • When the code above, if the business logic insertPerson () starts from a non-transactional method, a method in which the transaction call insert (), then when the insert () exception, invalid transaction control.

  • Simply put, that is in the same class, non-transactional method A calls method B transaction, the transaction method B when abnormal, transaction control ineffective, A and B will not be rolled back.

  • Then, in the same class, the transaction method A calls a non-transactional method B, then B is called non-transactional method transaction method C, if the transaction into effect? the answer is. A method because the transaction when calling external code, has opened a transaction management.

4.6. The data source is loaded transaction manager?

  • Section 3.3 mentioned in Article 5: should ensure that the data sources to be used are loaded in the calling method 事务管理器.

  • In SpringBoot project, if it is a single data source, the system will default to a single data source configuration transaction manager DataSourceTransactionManager.

  • In SpringBoot project, if it is a multi-data source, it must ensure that all data sources are configured transaction manager.

  • About configuration may refer to multiple data sources: https://blog.csdn.net/hanchao5272/article/details/81209552

  • Manual configuration transaction manager can refer to the following:

    @Bean
    @Primary
    public PlatformTransactionManager primaryTransactionManager(@Qualifier("sqlDataSource") DataSource sqlDataSource) {
      return new DataSourceTransactionManager(sqlDataSource);
    }
    

4.4. Trigger a rollback exception is configured correctly?

  • By default, the transaction is for the return uncheckof (a runtime exception) or ERROR exception.

  • By default, the checkexception does not trigger a rollback, such as FileNotFoundException.

  • If you want a simple configuration for all exceptions to roll back, you can do this:

    @Transactional(rollbackFor = Exception.class)
    

4.5. @ Transactional extended configuration propagation is correct?

  • Under normal circumstances, propagation properties without having to configure. It will use the default configuration, namely: Propagation.REQUIRED.
  • Some propagation properties cause the transaction will not trigger, must pay attention to:
    • SUPPORTS: If there is a transaction, the transaction is entered; otherwise, run in a non-transactional way.
    • NOT_SUPPORTED: If there is a transaction, the pending transaction, and run in non-transactional way.
    • NEVER: Running in non-transactional form, if there is a transaction, an exception is thrown.

4.7. Optional configuration transaction management is correct?

In SpringBoot, the configuration on the transaction There are two optional configuration (usually no configuration):

  1. Springboot start classes @EnableTransactionManagement.

  2. Springboot profile rollback-on-commit-failureattributes:

    # yaml配置
    spring:
      transaction:
        rollback-on-commit-failure: true
        
    # properties配置
    spring.transaction.rollback-on-commit-failure=true
    

Make sure that the above configuration is correct (or not configured).

Guess you like

Origin blog.csdn.net/hanchao5272/article/details/90343882