There are two kinds of transaction management: programmatic and declarative. Programmatic is to write transactions directly in code, while declarative is to annotate or configure in XML files, which is more convenient than programmatic.
Annotation via @Transactional is common. We can use @ EnableTransactionManagement annotations to enable the transaction management functions, the annotations can be added on to start the class or add a configuration class to handle alone.
The Transactional annotation property
- Name when there are multiple transactionmanagers in the configuration file, you can use this property to specify which TransactionManager to select.
- Propagation behavior of propagation transactions. The default value is REQUIRED.
- Isolation Isolation of a transaction. The DEFAULT value is DEFAULT.
- Timeout Specifies the timeout period for a transaction. The default value is -1. If the time limit is exceeded but the transaction has not completed, the transaction is automatically rolled back.
- Read -only Specifies whether a transaction is read-only. The default value is false. To ignore methods that do not require transactions, such as reading data, you can set read-only to true.
- Rollback-for specifies the types of exceptions that can trigger transaction rollback. If multiple exception types need to be specified, separate them by commas (,).
- No-rollback-for Throws the exception type specified by no-rollback-for without rolling back the transaction.
Propagation properties (Transaction Propagation)
- REQUIRED supports existing transactions and creates a new one if one does not already exist.
- MANDATORY supports transactions that already exist, and throws an exception if there are none.
- NESTED creates a NESTED transaction in the current transaction, or simply creates a new transaction if one is not already there.
- REQUIRES_NEW suspends the current transaction, creates a new one, or simply creates a new one if one doesn’t already exist.
- NEVER enforces not running in a transaction, and throws an exception if one currently exists.
- NOT_SUPPORTED forces not to run in a transaction and suspends it if one currently exists.
- SUPPORTS the current transaction. If there is no transaction, it will not run in the transaction.
Transactional applications
Transactional @Transactional can be added to methods to indicate that configuring transactions on the current method can also be added at the class level.
It can also be added at the class level. When the @Transactional annotation is placed at the class level, it means that all public methods of the class are configured with the same transaction attribute information.
When @Transactional is configured at the class level and @Transactional is configured at the method level, the application manages transactions with method-level transaction attribute information that overrode the class-level configuration information.
Transactional 3
Declarative transaction management consists of three components:
- Facets of a transaction
- Transaction manager
- The EntityManager Proxy itself
Facets of transaction ****
The transaction aspect is an “around” aspect that can be invoked before and after the annotated business method. The concrete class that implements the aspect is the TransactionInterceptor. Transaction facets have two main responsibilities:
- At ‘before’, the aspect provides a call point to determine whether the invoked business method should run within the scope of the ongoing transaction or start a new independent transaction.
- At ‘after’, the aspect needs to make sure the transaction is committed, rolled back, or continued.
When ‘before’, the transaction aspect itself does not contain any decision logic, and the decision whether to start a new transaction is delegated to the transaction manager.
Transaction manager
The transaction manager needs to address the following two issues:
- Should the new Entity Manager be created?
- Should YOU start a new transaction?
These need to be determined when the transaction aspect ‘before’ logic is invoked. The transaction manager makes decisions based on the following two points:
- Whether a transaction is in progress
- Propagation properties of transaction methods (for example, REQUIRES_NEW always starts a new transaction)
If the transaction manager determines that it wants to create a new transaction, it will:
- Create a new Entity Manager
- Entity Manager binds to the current thread
- Get the connection from the database connection pool
- Binds the connection to the current thread
Bind both the Entity Manager and the database connection to the current thread using the ThreadLocal variable. They are stored in the thread while the transaction is running, and when they are no longer used, the transaction manager decides whether to remove them. Any part of the program that needs the current Entity Manager and database connection can be retrieved from the thread.
EntityManager proxy
When a business method call is similar to the ** EntityManager.persist ()** method, this is not called directly by entityManager, but by a business method call proxy, because the transaction manager binds Entity Manage to a thread, The agent gets the current Entity Manager from the thread.
4, note
The 4.1@Transactional annotation applies to public methods for transaction management. Because AOP intercepts if the method is public:
/ / AbstractFallbackTransactionAttributeSource class protected TransactionAttribute computeTransactionAttribute (Method Method, Class<? > targetClass) { // Don't allow no-public methods as required. if (allowPublicMethodsOnly() && ! Modifier. IsPublic (method. GetModifiers ())) {return null; }}Copy the code
4.2 the propagation properties
The following three propagation can not start a transaction. If the three propagation modes are incorrectly configured, the transaction may not be rolled back.
- TransactionDefinition. PROPAGATION_SUPPORTS: if a transaction exists, then join the transaction; If there is no transaction currently, it continues in a non-transactional manner.
- TransactionDefinition. PROPAGATION_NOT_SUPPORTED: run way of transaction, if a transaction exists, suspending the current transaction.
- TransactionDefinition. PROPAGATION_NEVER: run way of transaction, if the current transaction, throw an exception.
4.3 rollbackFor properties
By default, if an unchecked exception (inherited from RuntimeException) or Error is thrown in a transaction, Spring rolls back the transaction; In addition, Spring does not roll back transactions. Other types of exceptions thrown in a transaction can be specified by rollbackFor to support transaction rollback, for example:
@Transactional(propagation= Propagation.REQUIRED, rollbackFor= MyException.class)
Copy the code
The transaction is also rolled back if the exception thrown in the target method is a subclass of the exception specified by rollbackFor.
4.4 In the default proxy mode, the target method can only be intercepted by Spring’s transaction interceptor if it is called externally. Direct calls to two methods in the same class are not intercepted by Spring’s transaction interceptor
Add transaction control to two methods in the same class, where transactions on method do not take effect. One method is to write it to another column and then call it in the current class
@Transactional(propagation = Propagation.REQUIRED)@Overridepublic void save() { method(); . If (true) {throw new RuntimeException("save exception "); }} @transactional (propagation = propagation.REQUIRES_NEW)public void method() {... Business processing}Copy the code