In Spring, we can free up from the tedious Transaction Management Code and flexibly manage transactions in declarative mode to improve development efficiency and quality.
When using Spring, most of them will use its declarative transactions, simple rule configuration in the configuration file, and the use of Spring's AOP function can easily deal with transaction problems; this involves the Propagation attribute of a transaction. It is defined in the TransactionDefinition interface for PlatfromTransactionManager. PlatfromTransactionManager is the core interface of spring transaction management.
TransactionDefinition public interface TransactionDefinition { int getPropagationBehavior(); int getIsolationLevel(); int getTimeout(); boolean isReadOnly(); } |
The getTimeout () method returns the number of seconds that the transaction must be completed.
IsReadOnly (): whether the transaction is read-only. The transaction manager can optimize the transaction based on the returned value to ensure that the transaction is read-only.
The getIsolationLevel () method returns the isolation level of the transaction. The transaction manager controls the data in another transaction according to it.
The TransactionDefinition interface defines five different transaction isolation levels. ISOLATION_DEFAULT is a default isolation level of PlatfromTransactionManager, which uses the default transaction isolation level of the database. the other four correspond to the JDBC isolation level. ISOLATION_READ_UNCOMMITTED is the lowest isolation level of the transaction. It allows others to see the uncommitted data of this transaction. This isolation level will generate dirty reads, which cannot be repeated and Phantom reads.
There are 7 options available in the TransactionDefinition interface:
PROPAGATION_REQUIRED: supports the current transaction. If no transaction exists, a new transaction is created. This is the most common choice.
PROPAGATION_SUPPORTS: supports the current transaction. If no transaction exists, it is executed in non-transaction mode.
PROPAGATION_MANDATORY: supports the current transaction. If no transaction exists, an exception is thrown.
PROPAGATION_REQUIRES_NEW: Creates a transaction. If a transaction exists, it is suspended.
PROPAGATION_NOT_SUPPORTED: executes operations in non-transaction mode. If a transaction exists, the current transaction is suspended.
PROPAGATION_NEVER: runs in non-transaction mode. If a transaction exists, an exception is thrown.
PROPAGATION_NESTED: supports the current transaction and adds a Savepoint, which is committed or rolled back synchronously with the current transaction.
Now we can describe it with an example and apply the preceding propagation attributes: declare two beans: ServiceA and ServiceB, where ServiceB is referenced;
ServiceA { void methodA() { ServiceB.methodB(); } } ServiceB { void methodB() { } } |
Next, let's analyze them one by one:
PROPAGATION_REQUIRED
If the transaction to be executed is not in another transaction, a new transaction is initiated. For example, ServiceB. the transaction level of methodB is defined as PROPAGATION_REQUIRED. serviceA. methodA has started the transaction and calls ServiceB. methodB, ServiceB. methodB sees that it is already running in ServiceA. within a methodA transaction, there will be no new transactions. However, if ServiceA. methodA finds that he is not in the transaction, it will assign a transaction to him. In this way, the transaction will be rolled back if an exception occurs in ServiceA. methodA or anywhere in ServiceB. methodB. Even if the ServiceB. methodB transaction has been committed, ServiceA. methodA will roll back in the next fail, and ServiceB. methodB will also roll back.
PROPAGATION_SUPPORTS
If the current transaction is running in the form of a transaction, if there is no longer a transaction, it will run in the form of a non-transaction.
PROPAGATION_MANDATORY
It must be run in a transaction. That is, it can only be called by one parent transaction. Otherwise, an exception is thrown.
PROPAGATION_REQUIRES_NEW
For example, we designed ServiceA. the transaction level of methodA is PROPAGATION_REQUIRED, ServiceB. the transaction level of methodB is PROPAGATION_REQUIRES_NEW. When it is executed to ServiceB. in methodB, ServiceA. the transaction where methodA is located will be suspended, ServiceB. methodB starts a new transaction and waits for ServiceB. after the methodB transaction is completed, he continues to execute. The difference between the PROPAGATION_REQUIRED transaction and PROPAGATION_REQUIRED is the transaction rollback degree. Because ServiceB. methodB is a new transaction, there are two different transactions. If ServiceB. methodB has been submitted, ServiceA. methodA fails to roll back, And ServiceB. methodB will not roll back. If ServiceB. methodB fails to roll back, if the exception it throws is caught by ServiceA. methodA, The ServiceA. methodA transaction may still be committed.
PROPAGATION_NOT_SUPPORTED
Transactions are currently not supported. For example, ServiceA. the transaction level of methodA is PROPAGATION_REQUIRED, and ServiceB. the transaction level of methodB is PROPAGATION_NOT_SUPPORTED. in methodB, ServiceA. the transaction of methodA is suspended, but it is finished in a non-transaction state, and then continues ServiceA. methodA transactions. Network Management Alliance bitsCN_com
PROPAGATION_NEVER
Cannot run in transactions. Assume that the transaction level of ServiceA. methodA is PROPAGATION_REQUIRED, and that of ServiceB. methodB is PROPAGATION_NEVER, then ServiceB. methodB throws an exception.
PROPAGATION_NESTED
The key to understanding Nested is savepoint. The difference between him and PROPAGATION_REQUIRES_NEW is that PROPAGATION_REQUIRES_NEW starts another transaction and will be independent of its parent transaction, while the Nested transaction and its parent transaction are dependent on each other, his submission must be done with his parent transaction. That is to say, if the parent transaction is finally rolled back, it will also be rolled back. The benefit of a Nested transaction is that it has a savepoint:
ServiceA { void methodA() { try { ServiceB.methodB(); } catch (Exception e) { ServiceC.methodC(); } } } |
That is, ServiceB. if methodB fails to roll back, ServiceA. methodA will roll back to the savepoint, ServiceA. methodA can select another branch, such as ServiceC. methodC, continue to execute, to try to complete your own transaction; but this transaction is not defined in the EJB standard.