Transactions supported by Spring

Spring provides two types of transaction management, programmatic and declarative.

  • programmatic: Manually enabling, committing, or rolling back transactions in a coded manner is more granular, but more cumbersome.
  • declarative: More convenient, but more granular, to implement transactions without invasion by wrapping them with annotations on a method or class or interface.

It is important to note that the database used needs to support transactions, otherwise transactions will not work. For example, MySql’s MyIsam engine does not support transactions.

Configuration of Spring transactions

Add the dependent

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>${spring.version}</version>
	</dependency>
Copy the code

Configure the transaction manager

	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<! If you use annotation-based declarative transactions, you need to configure annotation-driven -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
Copy the code

Obviously, the dataSource of The transactionManager should be the dataSource of the transaction in the code, otherwise how to manage it.

Use of programmatic transactions

To start, commit, or roll back a transaction in code:

	// Start transaction
	TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
	// Exception rollback does not have to be done in a try... In the catch
	transactionManager.rollback(status);
	// Commit the transaction
	transactionManager.commit(status);
Copy the code

Usually a more appropriate method of use:

	TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
	try {
		// Perform database operations that need to be in the same transaction.// The transaction is committed
		transactionManager.commit(status);
	} catch (SomeException) {
		// Error handling./ / rollback
		transactionManager.rollback(status);
	}
Copy the code

Use of declarative transactions

Add the @Transaction annotation directly to the class or method:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
public int save(Info info) throws Exception {
Copy the code

Common arguments to @Transaction annotations:

Propagation behavior

  • REQUIRED (default)Must run in a context with transactions: if there are no (outer) transactions currently, create a new one; Joins the current (outer) transaction if it currently exists. (If an exception occurs in the called method, both the calling method and the called method’s transaction are rolled back.) This is the most common choice.
  • SUPPORTSCurrent (outer) transactions are supported and non-transactionally executed if there are no current (outer) transactions.
  • MANDATORYEnforce the use of the current (outer) transaction and throw an exception if there is no current (outer) transaction.
  • REQUIRES_NEWCreate a new transaction and run in it, suspending the current (outer) transaction first if one exists
  • NOT_SUPPORTEDPerform non-transactionally: Suspend the current (outer) transaction if it currently exists.
  • NEVERNon-transactionally executed: Throws an exception if a (outer) transaction currently exists.
  • NESTEDExecute in a nested manner: if a (outer) transaction currently exists, it runs in a nested manner independently of its own transaction without affecting the current (outer) transaction, which must be rolled back if it is rolled back; If no (outer) transactions currently exist, perform operations similar to PROPAGATION.REQUIRED.

Isolation Isolation level

  • DEFAULTUse the database default transaction isolation level
  • READ_UNCOMMITTEDAllows reading of changes that have not yet been committed, potentially resulting in dirty reads, phantom reads, and unrepeatable reads
  • READ_COMMITTEDDirty reads are prevented by allowing reads from committed transactions, but phantom and unrepeatable reads are still possible
  • REPEATABLE_READMultiple reads of the same field give consistent results, unless the data is modified by the current transaction itself. Dirty and unrepeatable reads can be prevented, but phantom reads may still occur
  • SERIALIZABLEFully follow ACID isolation to ensure no dirty reads, non-repeatable reads, and phantom reads, but with minimal execution efficiency.

ReadOnly Indicates whether the transaction is read-only

Indicates whether the transaction only reads data but does not update it. Only the transaction for the read operation is set to read-only to help the database engine optimize the transaction.

Timeout Indicates the timeout period.

Avoid locking the database for a long time, in seconds.

RollbackFor Rolls back the exception class

By default, only runtime exceptions are rolled back, as shown below.

Pitfalls of declarative transactions

Class invocation

Spring’s declarative transactions are dynamically brokered via AOP, thus generating an implemented transaction brokered class, distinct from the original class. Consider a case:

  • Method A in the Service class does not declare A transaction
  • Method B in the Service declares a transaction
  • Method A internally calls method B

In this case, the method B calling Service uses the proxy class Service’, which implements the transaction method and will be rolled back if an exception occurs.

However, if method A is called and method B of the original Service class is used inside the proxy class, the transaction is not implemented and the exception rollback is not possible.

Solution: Split method B into other classes and use transaction wrapping to ensure that the proxy class is called instead of the original class’s methods.

Wrong use

Declarative transaction-wrapped methods roll back when a method throws an exception, but by default only when a RuntimeException is thrown.

If an exception is caught and swallowed, or if a non-runtimeException is thrown, the default is not to roll back.

Solution: Do not swallow exceptions and use the rollbackFor parameter of the @Transaction annotation to control non-runtimeExceptions.

The partial class hierarchy of java.lang in Java8 is as follows (see Resources at the bottom of this article for the full structure) :

java.lang.Object ...... java.lang.Throwable (implements java.io.Serializable) java.lang.Error java.lang.AssertionError java.lang.LinkageError java.lang.BootstrapMethodError java.lang.ClassCircularityError java.lang.ClassFormatError java.lang.UnsupportedClassVersionError java.lang.ExceptionInInitializerError java.lang.IncompatibleClassChangeError java.lang.AbstractMethodError java.lang.IllegalAccessError java.lang.InstantiationError java.lang.NoSuchFieldError java.lang.NoSuchMethodError java.lang.NoClassDefFoundError java.lang.UnsatisfiedLinkError java.lang.VerifyError java.lang.ThreadDeath java.lang.VirtualMachineError java.lang.InternalError java.lang.OutOfMemoryError java.lang.StackOverflowError java.lang.UnknownError java.lang.Exception java.lang.CloneNotSupportedException java.lang.InterruptedException java.lang.ReflectiveOperationException java.lang.ClassNotFoundException java.lang.IllegalAccessException java.lang.InstantiationException java.lang.NoSuchFieldException Java. Lang. NoSuchMethodException. / / this is a RuntimeException Java lang. RuntimeException Java. Lang. ArithmeticException java.lang.ArrayStoreException java.lang.ClassCastException java.lang.EnumConstantNotPresentException java.lang.IllegalArgumentException java.lang.IllegalThreadStateException java.lang.NumberFormatException java.lang.IllegalMonitorStateException java.lang.IllegalStateException java.lang.IndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException java.lang.NegativeArraySizeException java.lang.NullPointerException java.lang.SecurityException java.lang.TypeNotPresentException java.lang.UnsupportedOperationException ......Copy the code

The resources

Spring declarative transactions – Simple book

Spring declarative transactions within the same class method call transaction invalidation – Cloud Community – Ali Cloud (ps. This is not the original. I can’t find the original.

java.lang Class Hierarchy (Java Platform SE 8 )

This article moves my blog, welcome to visit!