Your comment @Transaction failure yet?

introduction

In the project we will often use @Transaction annotation for transaction control, but sometimes inexplicable without this transaction control does not work, during the interview, the interviewer might ask @Transaction comment Under what circumstances would fail? Today I just I see an article written about this, so we sort out.

A Transaction

We know that in the spring to be performed in the framework of transaction control, we have two ways. First, [ programmatic transaction control ], second [ declarative transaction control ].

[ Programmatic transaction control ]

Concept: As the name suggests, is what we can control the transaction by way of programming code

Disadvantages: Code highly invasive

Example:

try {
    //TODO something
     transactionManager.commit(status);
} catch (Exception e) {
    transactionManager.rollback(status);
    throw new InvoiceApplyException("异常失败");
}

[ Declarative transaction control ]

Concept: Based on AOP Aspect-oriented, and it will be specific business transaction Partial decoupling.

Pros: Code Code decoupling transaction control and our specific business, code, less invasive. Therefore, the actual development process, this approach is the most used. Declarative transaction, there are two ways, one is based on xml configuration file and TX mode of AOP , the second is based on @Transaction comment

Two, @ Transaction introduction

  1. @ Transaction annotation can be used in place

    @Transaction can act interfaces, classes, class methods

  • Action class: public class's methods are configured with the same transaction attribute information.
  • The role of class methods: class configuration when a @Transaction, the method also configure @Transaction, the transaction will override the class method of transaction configuration information
  • Role Interface: This method is not recommended, because once marked on the Interface and configure Spring AOP using dynamic proxy CGLib, will lead to failure @Transaction comment  
@Transactional
 @RestController
 @RequestMapping
 public class MybatisPlusController {
     @Autowired
     private CityInfoDictMapper cityInfoDictMapper;
 
     @Transactional(rollbackFor = Exception.class)
     @GetMapping("/test")
    public String test() throws Exception {
        CityInfoDict cityInfoDict = new CityInfoDict();
        cityInfoDict.setParentCityId(2);
        cityInfoDict.setCityName("2");
        cityInfoDict.setCityLevel("2");
        cityInfoDict.setCityCode("2");
        int insert = cityInfoDictMapper.insert(cityInfoDict);
        return insert + "";
    }
}

2. @ Transaction properties

①propagation

propagation propagation behavior on behalf of the transaction. The default value Propagation.REQUIRED.

 

Propagation.REQUIRED: If the current transaction exists, it is added to the transaction, if the transaction does not currently exist, create a new transaction (that is, if A and B methods are methods to add annotations in the default propagation mode, A method. internal call B, the transaction will merge the two methods a transaction)

Propagation.SUPPORTS: If the current transaction exists, it is added to the transaction; if the transaction does not currently exist, the non-transactional way to continue to run

Propagation.MANDATORY: If the current transaction exists, it is added to the transaction, if the transaction does not currently exist, an exception is thrown.

Propagation.REQUIRES_NEW: re-create a new transaction, if the transaction currently exists, suspend the current transaction (Method A in a current default mode Propagation.REQUIRED, b plus the method of class B mode Propagation.REQUIRES_NEW employed, then. a method call b method to operate the database, but after a method throws an exception, b method does not roll back a transaction will be suspended because Propagation.REQUIRES_NEW method)

Propagation.NOT_SUPPORTED: by way of non-transactional operation, if the current transaction exists, suspend the current transaction

Propagation.NEVER: by way of non-transactional operation, if the current transaction exists, an exception is thrown

Propagation.NESTED: and Propagation.REQUIRED the same effect.

②isolation property

isolation: isolation level of the transaction

③timeout property

Transaction timeout, the default value is -1. If the transaction exceeds the time limit has not been completed yet, the automatic rollback.

④readOnly property

Specify whether the transaction is read-only transactions, the default is false; method which does not require the transaction to ignore, such as reading data, can be set to true

⑤rollbackFor property

Is used to specify the type of transaction rollback can trigger an exception, you can specify multiple exception types

⑥noRollbackFor property

Specifies the exception type is thrown, the transaction will not change, you can also specify multiple exception types.

Three, @ Transaction failure scenarios

① applied to the non-modified public methods. The reason is because the failure Spring AOP agent is, as shown, TransactionInterceptor (transaction interceptor) to intercept target before and after method execution, DynamicAdvisedInterceptor (CglibAopProxy inner class) intercept method JDKDynamicAopProxy or indirectly invoke method calls computeTransactionAttribute AbstractFallbackTransactionAttributeSource method of obtaining transaction annotation transaction configuration information.

protected TransactionAttribute computeTransactionAttribute(Method method,
    Class<?> targetClass) {
        // Don't allow no-public methods as required.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
}

This method checks the target method modifiers when configuration information public, not the public will not get @Transaction of property.

② annotation attribute error propagation properties.

If the configuration following three propagation attribute = attribute value, no transaction for rollback.

TransactionDefinition.PROPAGATION_SUPPORTS

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

TransactionDefinition.PROPAGATION_NEVER

③rollbackFor setting error

rollbackFor prescription can be specified transaction rollback exception types .Spring default dished out unchecked unchecked exceptions (inherited from RuntimeException exception) or Error only roll back the transaction; other prescriptions exception does not roll back the transaction, if thrown in a transaction other types of exceptions, but they can expect Spring roll back the transaction, you need to specify rollbackFor property.

If thrown in the target method in a subclass of abnormal abnormal rollbackFor specified, the transaction will also be rolled back.

private int getDepth(Class<?> exceptionClass, int depth) {
         if (exceptionClass.getName().contains(this.exceptionName)) {
             // Found it!
             return depth;
 }
         // If we've gone as far as we can go and haven't found it...
         if (exceptionClass == Throwable.class) {
             return -1;
}
return getDepth(exceptionClass.getSuperclass(), depth + 1);
}

④ call the same method in a class, resulting in failure @Transaction

For example, there is a class Test, it's a method A, A and then call this type of method B (regardless of method B is public or private modification), when the method is not declared annotation affairs, while the B methods, after the Method A is tail-call, transaction method B is not functioning. this is because the use of spring AOP proxy caused, because only when the transaction method is called the current class that the code will have a spring proxy object generated by the management.

⑤ exception is your catch "eat" @Transaction lead to failure.

This situation is the most common type of failure scenarios @Transaction comment

     @Transactional
      Private Integer A () throws Exception {
          int INSERT = 0 ;
          the try { 
             CityInfoDict cityInfoDict = new new CityInfoDict (); 
             cityInfoDict.setCityName ( "2" ); 
             cityInfoDict.setParentCityId ( 2 );
              / ** 
              * 2 A field is inserted data 
             * / 
            iNSERT = cityInfoDictMapper.insert (cityInfoDict);
             / ** 
             * B 3 is inserted into the data field 
             * / 
            b.insertB (); 
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

If the internal B method throw an exception, but this time try catch A method of abnormal B method, and that the transaction can be rolled back to normal yet?

Answer: No!

会抛出异常:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

Because when ServiceB thrown an exception later, ServiceB need to sign the current transaction rollback. ServiceA due time you manually capture this exception handling, ServiceA that the current transaction should commit to normal. At this time there will be an inconsistency, too It is such that the front UnexceptedRollbackException throws an exception,

Spring is a transaction before calling the start of a business method is performed only after the business method completes commit or rollback, if there is executed depending on whether an exception is thrown runTime. If you throw runTimeException did not catch on to your business methods, then, the transaction is rolled back.

In business methods generally do not need to catch an exception, if you must catch must be thrown out throw new RuntimeException(), or throw an exception specified annotation type @Transactional(rollbackFor=Exception.class), otherwise it will cause the transaction to fail, resulting in inconsistent data commit data, so sometimes try catch the rather superfluous.

database engine does not support transactions

The probability of this happening is not high, the transaction can take effect transactional database engine supports is the key. Commonly used MySQL database supports transactions using the default innodbengine. Once the database engine does not support switching to a transaction myisam, that transaction will fail fundamentally.

[From above] marcozheng public number, https: //mp.weixin.qq.com/s/enKOM3F_Xxg123HPMCFUPw, and collated.

 

Guess you like

Origin www.cnblogs.com/lovehunterYjj/p/12588532.html