Transaction management is an essential part of application system development. Spring provides rich feature support for transaction management. Spring transaction management is divided into two ways: coded and declarative. Programmatic transactions refer to the implementation of transactions by encoding, and declarative transactions are based on AOP, which decouple the specific business logic from the transaction. Declarative transaction management makes business code logic non-polluting, so declarative transactions are more used in real-world use. There are two ways to declare a transaction, one is to make a related transaction rule declaration in the configuration file (XML), and the other is based on the @transactional annotation method. Note Configuration is a popular way to use, so this article will focus on transaction management based on @transactional annotations.
Set the propagation property of the @transactional correctly
Note that the following three types of propagation can not start a transaction. The target method would have been expected to do transaction management, but if the three kinds of propagation are misconfigured, the transaction will not be rolled back.
- Transactiondefinition.propagation_supports: If a transaction is currently present, the transaction is joined, and if no transaction is currently present, it will continue in a non-transactional manner.
- Transactiondefinition.propagation_not_supported: Runs in a non-transactional manner, suspending the current transaction if a transaction is currently present.
- Transactiondefinition.propagation_never: Runs in a non-transactional manner and throws an exception if a transaction is currently present.
Set the Rollbackfor property of the @transactional correctly
By default, if you throw an unchecked exception (an exception that inherits from RuntimeException) or Error in a transaction, spring rolls back the transaction, except that spring does not roll back the transaction.
If you throw other types of exceptions in the transaction and expect Spring to rollback the transaction, you can specify Rollbackfor. Cases:
@Transactional (propagation= propagation.required,rollbackfor= myexception.class)
By analyzing the Spring source, it is known that if the exception thrown in the target method is a subclass of the exception specified by Rollbackfor, the transaction will also be rolled back.
@Transactional only valid if the public method is applied
Only @transactional annotations are applied to the public method for transaction management. This is because when you use the Spring AOP Proxy, spring calls the transactioninterceptor in Figure 1 before and after the target method is executed. The Intercept method of the Dynamicadvisedinterceptor (Cglibaopproxy's inner Class) or the Jdkdynamicaopproxy invoke method indirectly invokes the Abstractfallbacktransactionattributesource (Spring uses this class to get table 1.) The Computetransactionattribute method that @Transactional the Transaction property configuration property information for the annotation.
Protected TransactionAttribute Computetransactionattribute (method, class<?> targetclass) { // Don ' t allow no-public methods as required. if (allowpublicmethodsonly () &&! Modifier.ispublic (Method.getmodifiers ())) {return null;}
This method checks whether the modifier of the target method is public, and if it is not public, it will not get the @transactional property configuration information, and will eventually result in transaction management without using Transactioninterceptor to intercept the target method.
Avoid the self-invocation problem of Spring AOP
Under Spring's AOP proxy, only the target method is externally invoked, and the target method is managed by the spring-generated proxy object, which can cause self-invoking problems. If other methods within the same class that do not have @transactional annotations are called internally with a @transactional annotation method, the transaction with the @transactional annotation method is ignored and no rollback occurs.
Finally, these two problems can be solved by replacing the Spring AOP proxy with AspectJ.
Original: https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html
Spring Transaction Management Transactional usage considerations