Spring declarative transaction @Transaction annotation -- isolation level and propagation characteristics

Posted by khr2003 on Thu, 29 Aug 2019 09:37:55 +0200

Isolation level

Define how much a transaction is affected by other concurrent transactions.

Problems caused by transaction concurrency

  • Dirty Reading: One transaction reads data modified by another transaction that has not yet been submitted
  • Non-repeatable reading: After a transaction reads data, the data is modified by other transactions, at which time the first transaction reads the data may be inconsistent (emphasis on change)
  • Hallucination: A transaction reads some data, and when it does not submit for readout, it has more or less data, similar to hallucination (emphasis on additions and deletions).
  • Lost modifications: Both transactions read the data, and after one transaction has been modified, the other transaction has also been modified, and the modification of the former is lost.

Five isolation levels (RU, RC, RR, Serializable)

  • ISOLATION_DEFAULT: Using database default, oracle default RC, mysql default RR
  • ISOLATION_READ_UNCOMMITTED: Unsubmitted data can be read without resolving the above problems

         

  • ISOLATION_READ_COMMITTED: Readable submitted data, dirty reading only
  • ISOLATION_REPEATABLE_READ: Reading data from a field several times with the same result can solve dirty reading and non-repeatable reading, but it may still be illusory reading.
  • ISOLATION_SERIALIZABLE: Serial not concurrent, solve all problems


 

Transaction Communication Behavior

Describes how transactions propagate when a method modified by transaction propagation behavior is nested into another method.

Seven Communication Behaviors

  • PROPAGATION_REQUIRED: When there are peripheral transactions, they join to form the same transaction. When there are no peripheral transactions, they are newly opened. Internal affairs are independent of each other.
  • PROPAGATION_REQJIRES_NEW: Whether or not peripheral transactions open new transactions, independent of each other, and independent of each other with peripheral affairs
  • PROPAGATION_SUPPORTS: If there is no transaction on the periphery, it is not transactional, and if there is a transaction, it is the same as REQUIRED.
  • PROPAGATION_NOT_SUPPORT: Non-transactional execution, suspended if a transaction exists outside
  • PROPAGATION_MANDATORY: Use peripheral transactions and throw exceptions if there are no peripheral transactions
  • PROPAGATION_NEVER: Non-transactional execution, throws an exception when there is a transaction on the periphery
  • PROPAGATION_NESTED: If there is no transaction on the periphery, it is independent of opening new transactions within REQUIRED. If there are peripheral transactions, the internal transaction is its sub-transaction, while the main transaction rolls back all the sub-transactions, and the sub-transaction rollback does not affect other sub-transactions and the main transaction.

 

In Spring's @Transaction, there is an important attribute: Propagation, which refers to the propagation behavior of transactions when nested calls occur between transaction methods (the transaction of the method currently invoked, and the relationship between other current transactions).
In Transaction Definition, seven transaction propagation behaviors are defined. Here is a brief record.
Take a look at the source code for Propagation:

public enum Propagation {

	//Default values
	//If there is a transaction at present, join the transaction. If there is no transaction, create a new one.
	REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
	
  	//If there is a transaction at present, join the transaction. If there is no transaction, it will be executed in a non-transactional way.
	SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

	//If there is a transaction, join it. If there is no transaction, throw an exception.
	MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

	//Create a new transaction execution and suspend the current transaction if there is one.
	REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

	//Execute in a non-transactional state and suspend the current transaction if there is one
	NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

	//Executing in a non-transactional state throws exceptions if there are currently transactions
	NEVER(TransactionDefinition.PROPAGATION_NEVER),

	/**
	 * Execute within a nested transaction if a current transaction exists,
	 * behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.
	 * <p>Note: Actual creation of a nested transaction will only work on specific
	 * transaction managers. Out of the box, this only applies to the JDBC
	 * DataSourceTransactionManager when working on a JDBC 3.0 driver.
	 * Some JTA providers might support nested transactions as well.
	 * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
	 */
	 //If there is a transaction at present, a new transaction will be created, which will be executed nestedly. If there is no transaction at present, a new transaction will be executed.
	 //This article looks at different articles, the statement is inconsistent, it is recommended to look at the source code comments.
	NESTED(TransactionDefinition.PROPAGATION_NESTED);
	
	private final int value;

	Propagation(int value) { this.value = value; }

	public int value() { return this.value; }

}

 

Topics: JDBC less Database Oracle