The fundamentals of Spring transactions

The essence of Spring transactions is the transaction support of the database. Without the transaction support of the database, Spring cannot provide transaction functionality. For pure JDBC-operated databases, to use transactions, follow these steps:

  1. Get connected Connection con = DriverManager. GetConnection ()

  2. Enable transaction con.setAutoCommit(true/false);

  3. Perform the CRUD

  4. Commit/rollback transaction con.mit ()/con.rollback();

  5. Conn.close ();

Using Spring’s transaction management capabilities, we can stop writing the code for steps 2 and 4 and let Spirng do it automatically. So how does Spring start and close transactions before and after we write CRUD? Solve this problem, and you can understand Spring’s transaction management implementation as a whole. The following is a brief introduction of the annotation method as an example

  1. The config file turns on the annotation driver, which identifies the Transactional classes and methods with the @transactional annotation.

  2. Spring will parse and generate the beans at startup, look at the classes and methods that have the annotations, generate a proxy for those classes and methods, and configure and inject them according to @Transaction parameters. This will dispose of the Transaction in the proxy for us. Exception rollback transaction).

  3. The real database layer commits and rolls back transactions through binlog or redo log.

Spring’s transaction mechanism

All data access technologies have transaction mechanisms that provide apis to start transactions, commit transactions to complete data operations, or roll back data in the event of an error. Spring’s transaction mechanism uses a unified mechanism to handle transactions of different data access technologies. Spring’s transaction mechanism provides a PlatformTransactionManager interface, different data access technology business use different implementations of the interface, as shown in table:

Data access technology

implementation

JDBC

DataSourceTransactionManager

JPA

JapTransactionManager

Hibernate

HibernateTransactionManager

JDO

JdoTransactionManager

Distributed transaction

JtaTransactionManager

The code that defines the transaction manager in the program is as follows:

@Bean 
public PlatformTransactionManager transactionManager() { 
	JpaTransactionManager transactionManager = new JpaTransactionManager(); 
	transactionManager.setDataSource(dataSource()); 
	return transactionManager; 
}
Copy the code

Nominal transaction

Spring supports declarative transactions, which use annotations to select methods that require transactions. It uses the @Transactional annotation to indicate ona method that requires transaction support. This is an AOP-based implementation.

import org.springframework.transaction.annotation.Transactional; @Transactional public void saveSomething(Long ID, String name) {Copy the code

Transactional annotation attribute

  • RollbackFor: An exception that triggers a rollback. The default values are RuntimeException and Error

  • DEFAULT is isolation. DEFAULT is the DEFAULT isolation level of the database itself. For example, MySQL is ISOLATION_REPEATABLE_READ

Ps: the network also said to add annotations on @ SpringBootApplication @ EnableTransactionManagement, is no longer need

Propagation properties of Spring transactions

Spring transaction propagation refers to the rule that multiple methods that contain transactions handle transactions when nested calls are made. For example, in the figure below, when transaction method A calls transaction method B, the inner transaction B is merged into the outer transaction calling method A and still starts its own transaction. In addition, if merged into an outer transaction, will the outer method be rolled back when the inner method is rolled back? In everyday development environments, the most commonly used transaction propagation behavior is REQUIRED and REQUIRES_NEW

propagation_required

Spring’s default transaction propagation behavior is propagation_REQUIRED, which means that the current method B joins the outer method if the outer method A has opened the transaction, and the current transaction opens A transaction if the outer method does not. This propagation behavior ensures that multiple nested transaction methods are executed within the same transaction, that is, multiple transaction methods can be committed or rolled back simultaneously. This mechanism satisfies most business scenarios.

propagation_requires_new

The propagation behavior is to start a new transaction each time. If the outer calling method A has already started A transaction, it suspends the outer transaction, executes the new transaction for the current method B, and resumes the execution of the upper transaction. In this way, when the inner method B throws an exception to roll back its own transaction, the execution of the outer transaction method will not be affected

propagation_supported

This propagation behavior means that if the outer method A opens the transaction, the current method B joins the outer transaction. If there is no transaction in outer layer A, then the current method B does not create A new transaction and executes it nontransactionally.

propagation_not_supported

This propagation behavior does not support transactions. That is, if the outer caller starts a transaction, the outer transaction is suspended, the current method logic is executed nontransactionally, and the outer transaction is resumed when the execution is complete.

propagation_never

This propagation behavior does not support transactions. That is, if outer caller A starts A transaction, an exception will be thrown before the current method B is executed. That is, caller A cannot start the transaction

propagation_mandatory

This propagation behavior means that a method configured with this propagation can only be called within a method that already has a transaction. If called from a method where there is no transaction, an exception is thrown. Caller A must start the transaction, or caller B will report an error

Proppagation_nested

If a transaction exists in the outer layer, the current method B is merged into the outer transaction. If no transaction exists, the transaction is currently enabled, propagating consistent with PROPAGATION_REQUIRED. When a transaction is rolled back, it can be rolled back to a savepoint to avoid all nested transactions being rolled back. The following is an example to introduce its propagation behavior:

@Transactional(rollbackFor = Exception.class, Propagation = propagation.REQUIRED) public void methodA() {//1.1 insert() system.out.println ("save something to db"); Savepoint savePoint savepoint savepoint savepoint savepoint savepoint try{serviceb.methodb (); }catch(Exception e){} //1.3 Update (); } @Service public class ServiceB { @Transactional(rollbackFor = Exception.class, NESTED) public void methodB() {insert(); System.out.println("save something to db"); }Copy the code

In this code, when methodA is executed, if the caller does not open the transaction, it opens a transaction and then performs an insert; When methodB is NESTED, a savepoint is created to mark the insert operation performed by code 1.1. MethodB is then executed using methodA to open the transaction. If methodB throws an exception, the methodB insert will be rolled back, but methodA’s 1.1 insert will not be rolled back. MethodB is rolled back only to the point at which the savePoint point was created, and when methodB is rolled back, both code 1.1 and code 1.3 are committed to the database

How to select the appropriate isolation sector in different business scenarios

// TODO

Database isolation level

Isolation level

Isolation level

Value of the isolation level

Resulting problems

Read-Uncommitted

Read uncommitted

0

Lead to dirty reads

Read-Committed

Read the submission

1

Avoid dirty reads and allow unrepeatable and phantom reads

Repeatable-Read

Repeatable degrees

2

Avoid dirty read, do not repeat read, allow magic read

Serializable

serialization

3

Serialized read, transactions can only be executed one by one, avoiding dirty read, unrepeatable read, phantom read. The execution efficiency is slow and the use is cautious

Not considering isolation raises security issues:

  • Dirty read: Transaction A adds, deletes, or modifies data, but does not commit it. Transaction B can read data that transaction A does not commit. If transaction A rolls back at this time, transaction B reads dirty data.

  • Non-repeatable reads: Transaction A initiates two read operations during execution. Between the first read operation and the second read operation, transaction B updates the data. In this case, the two reads are inconsistent. That is, one transaction read update data already committed by another transaction, resulting in inconsistent results for multiple queries.

  • Phantom read: transaction A makes batch changes to A range of data, and transaction B inserts A single data in this range. The first transaction loses the changes to the new data. That is, one transaction reads insert data that another transaction has already committed, resulting in inconsistent results for multiple queries.

Which isolation segments should be selected for different business scenarios

  • Bank statements do not allow phantoms

// TODO

Isolation levels in Spring

constant

explain

ISOLATION_DEFAULT

This is a PlatfromTransactionManager default isolation level, using the database default transaction isolation level. The other four correspond to JDBC isolation levels.

ISOLATION_READ_UNCOMMITTED

This is the lowest isolation level for a transaction and allows another transaction to see the uncommitted data of that transaction. This isolation level produces dirty reads, non-repeatable reads, and phantom reads.

ISOLATION_READ_COMMITTED

Ensure that data modified by one transaction is committed before it can be read by another transaction. Another transaction cannot read uncommitted data from that transaction.

ISOLATION_REPEATABLE_READ

This transaction isolation level prevents dirty, non-repeatable reads. But illusionary reading can occur.

ISOLATION_SERIALIZABLE

This is the most expensive but reliable transaction isolation level. Transactions are processed for sequential execution.

// The TODO database is isolated by views and locks. Spring’s isolation level should be tested.

Spring Boot support for transactions

Through the org. Springframework. Boot. Autoconfigure. Transaction. TransactionAutoConfiguration class. We can see that Spring Boot automatically turns on support for annotation transactions

Some concepts of read-only transactions (@Transactional(readOnly = True))

During the process from the point set at this point (point A) to the end of this transaction, data committed by other transactions will not be visible to that transaction! (Data submitted by others after point A will not appear in the query).

@transcational (readOnly=true) This annotation is typically written on business classes or their methods to add transaction control to them. Adding readOnly=true to the parentheses tells the underlying data source that this is a read-only transaction, which has some speed optimization for JDBC. The isolation level of transactions is DEFAULT, that is, to follow the isolation level of underlying data sources. The propagation of transactions is REQUIRED, so transactions will still exist. Generation throws a RuntimeException in the code, which still causes the transaction to roll back.

Application:

  1. If you execute a single query at a time, there is no need to enable transaction support. By default, the database supports read consistency during SQL execution.

  2. If you execute multiple queries, statistical query, for example, the report query, in this scenario, the multiple query SQL must ensure that the overall read consistency, otherwise, after the SQL query of the preceding article, the article after the SQL query, data changes by other users, then the total time of statistics query will be read data inconsistent state, at this time, Transaction support should be enabled.

handling

Deep understanding of the Spring transaction principle my.oschina.net/xiaolyuh/bl…

Geek’s Daily lesson, your understanding of Spring’s propagation features