[Transaction] springboot

Editor:

  https://blog.csdn.net/cp026la/article/details/86496788

Nonsense:

  Complex business logic in a request may be necessary to operate the database, to ensure that a Service approach multiple operations simultaneously dao success (failure), the configuration of the transaction is very important.

Probably three cases:

  1, a distributed transaction: the multi-module transaction, a distributed transaction is recommended to avoid to avoid, you can use the messaging middleware processing, but can not be fully resolved.
  2, multi-threaded transaction: //blog.csdn.net/kongkongyanan/article/details/81703415: Reference: https
  most, here are two 3 single module affairs, the focus of this chapter, also encountered in the development kinds of configurations.

  This chapter notes were used @Transactional (springboot default recommended) and the AOP global configuration mode:

pom dependent (continuation of the last chapter code) dependent increase in the aop:

<!-- aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

First, the transaction demonstrates:

Requires the introduction of spring-boot-starter-jdbc-dependent, but we integrated mybatis, already it contains the dependency, need not be repeated introduction.
1, controller level code: add test method in the UserController

 @GetMapping
 @RequestMapping(value = "add/{number}")
 public ApiResult add(@PathVariable("number") Integer number){
      userService.addUser(number);
      return ApiResult.ok();
 }

2, service-level code: add UserService the test method provided a controllable divide by zero exception

    public void addUser(int number){
        User user = new User();
        user.setId(22);
        user.setName("xiaoming");
        user.setAge(12);
        mapper.insertSelective(user);

        int num = 10/number;

        User user2 = new User();
        user2.setId(23);
        user2.setName("xiaohong");
        user2.setAge(90);
        mapper.insertSelective(user2);
    }  

3, test
3.1, request interface: http: // localhost: 8080 / user / add / 10 normal insertion of two data database

3.2, delete the two data just inserted. Request interface: http: // localhost: 8080 / user / add / 0 manufacturing division by zero exception.
Description: In this case only the database data is inserted into the first (xiaoming).
Analysis: Before inserting the second data (xiaohong), appear abnormal division by zero, resulting in a program interruption.

Requirements: This either while successfully operating in multiple dao same logic, either at the same time fail, do not allow a situation dao only successful operation appears.

Second, the use @Transactional configure the transaction:

1, add annotation on the service layer @Transactional method addUser

    @Transactional(rollbackFor = Exception.class)
    public void addUser(int number){
       ...
    }

 

2, the test: Remove the database has been successfully inserted.
2.1, request interface: http: // localhost: 8080 / user / add / 0 manufacturing division by zero exception.
2.2 Result: divide by zero exceptions, the database does not insert any data that implements multiple operations simultaneously dao success, while failure.

3, notes:

1, spring roll back the transaction default is abnormal (RuntimeException) and error (Error) is running, non-detection of abnormalities, such as SQLException will not be rolled back. Plus rollbackFor = Exception.class solve.
2, using a try catch catch that exception, the transaction will not be rolled back in service, because the try after the catch exception is equivalent to no abnormalities, abnormal unified treatment is recommended in the controller.

Third, the use AOP global processing services:

We need to introduce aop dependency.

1, the new configuration class global transaction (config placed into individual packages, convenient management):

/ ** 
 * Spring AOP configuration global transaction 
 * / 
@Aspect 
@Configuration 
public class TransactionAdviceConfig { 

    / * 
     * pointcuts 
     * execution () is the most common tangent point function 
     * execution (com.coolron.user.service.impl .. * * (..)). 
     *. 1, Execution (): expression body. 
     * 2, a * Number: indicates the return type, * represents the number of all types. 
     * 3, the package name: Indicates the need to intercept the package name, the latter two periods represents the current package and the current package of all the sub-packages, com.sample.service.impl package, all descendants of the class method under the package. 
     * 4, the second asterisk: Indicates the class name, asterisk represents all classes. 
     * 5, * (..): This last asterisk indicates the method name, asterisk represents all the way back inside the parentheses represents the parameters of the method, two periods indicate any parameters. 
     * / 
    Private Final static String AOP_POINTCUT_EXPRESSION = "Execution (com.coolron.user.service.impl .. * * * (..).)"; 

    @Autowired 
    Private the PlatformTransactionManager the transactionManager;

    @Bean
    public TransactionInterceptor txAdvice() {

        DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
        txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
        txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        txAttr_REQUIRED_READONLY.setReadOnly(true);

        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        // service 中方法前缀
        source.addTransactionalMethod("add*", txAttr_REQUIRED);
        source.addTransactionalMethod("save*", txAttr_REQUIRED);
        source.addTransactionalMethod("delete*", txAttr_REQUIRED);
        source.addTransactionalMethod("update*", txAttr_REQUIRED);

        return new TransactionInterceptor(transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }

}  

2, the test:
the @Transactional on Service in addUser method annotated comments, delete data.
2.1, request interface: http: // localhost: 8080 / user / add / 10 normal operation, the database data is inserted into two.
2.2, delete the two data just inserted. Request interface: http: // localhost: 8080 / user / add / 0 manufacturing division by zero exception.
Result: The exception occurs, the database does not insert data.

3, notes:

1, the entry point position properly configured, the configuration chapter:
Execution (. * Com.coolron.user.service.impl ... (...)), the user may specify a plurality of positions to *
2, service layer method name should be strictly in accordance with the rules of the global transaction configuration defined in the class to name.
3, also do not use the service in try catch.

Thus, a single module configuration transaction has been completed, is most usually encountered in the development of, for distributed transactions (i.e., multi-module), the possible transaction involving the business logic module into a process, using a message processing middleware nor is it the best option.

Guess you like

Origin www.cnblogs.com/wjqhuaxia/p/12148865.html