spring transaction creation and transaction propagation mechanism

1, Create transaction

1. Configure transaction manager

<!--    Configure data sources  dbcp2  -->
        <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
            <property name="driverClassName" value="${db.driver}"></property>
            <property name="url" value="${db.url}"></property>
            <property name="username" value="${db.username}"></property>
            <property name="password" value="${db.password}"></property>
        </bean>

        <!--   Configure transaction manager     -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--   Configure transaction support classes     -->
        <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

2. Using annotations

2.1 annotation

The annotation class indicates that all methods in this class turn on transactions

@Transactional(propagation = Propagation.REQUIRED)
@Service("addUserImpl1")
public class AddUserImpl1 implements IUser1 {

    @Override
    public void addUser1() {
        User user=new User();
        user.setSn("aa");
        user.setCn("bb");
        user.setSex(null);
        personMapper.insert(user);

    }
}

2.2 annotation method

The annotation method indicates that the method is specified to start the transaction

@Service("addUserImpl1")
public class AddUserImpl1 implements IUser1 {
	
	@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addUser1() {
        User user=new User();
        user.setSn("aa");
        user.setCn("bb");
        user.setSex(null);
        personMapper.insert(user);

    }
}

2, Propagation mechanism of transaction

1. Promotion.required (default)

The current transaction is supported. If there is no current transaction, a new transaction will be created
If there is a current transaction (there is a transaction in the outer method), join the current transaction and merge into one transaction
If a transaction already exists in the context, it will be added to the transaction for execution. If there is no transaction in the current context, a new transaction will be created for execution. Therefore, this level can usually meet most business scenarios

Outer transaction: @ Transactional(propagation = Propagation. *) or no transaction
Inner transaction: @ Transactional(propagation = Propagation.REQUIRED)
An outer transaction calls an inner transaction

If there is a transaction (current transaction) in the outer layer, the inner layer transaction is added to the outer layer transaction, one commit and one rollback (if an exception occurs in the inner layer and is not captured, the outer layer cannot capture the exception at this time, because rollback only = true must be rolled back, so the inner and outer layers can be rolled back together (this situation can be changed to SUPPORT) ; if an inner transaction catches an exception, the inner and outer transactions do not need to be rolled back). If there is no transaction in the outer layer, create a new transaction execution (at this time, there are only transactions in the inner layer, and the inner and outer layers do not affect each other; no matter who has an exception in the inner layer or outer layer and is not captured, it will not affect each other)

2,Propagation.REQUIRES_NEW

Create a new transaction. If there is a current transaction, suspend the current transaction
This method will commit the transaction independently and is not affected by the caller's transaction. If the parent is abnormal, it is also committed normally

Outer transaction: @ Transactional(propagation = Propagation. *) or no transaction
Inner transaction: @ transactional (propagation = propagation. Requirements_new)
An outer transaction calls an inner transaction

Whether or not there are transactions in the outer layer, a transaction is created in the inner layer. When an exception occurs in the inner transaction and the exception is thrown to the outer layer, the inner transaction is rolled back; If the outer layer does not catch the exception thrown by the inner layer, the transaction in the outer layer will be rolled back; Otherwise, rollback is not allowed; When an exception occurs in an inner layer transaction and the exception is caught, the inner and outer layers do not need to roll back
Summary: the inner and outer layers are independent of each other. If an exception occurs in a layer but no exception is caught, the layer will roll back; If there are no exceptions or exceptions have been caught, submit normally

3,Propagation.NESTED

If there is a transaction, it will become a sub transaction of the outer transaction. The method is not committed after the end of the method. It is only committed after the end of the outer transaction
If there are no transactions in the outer layer, a new transaction is created
If it is abnormal, the parent can catch its exception without rollback and commit normally
However, if the outer layer is abnormal, the inner layer must roll back (when there are transactions in the outer layer), which is called and requirements_ New differences

4,SUPPORTS

If a transaction currently exists, join the transaction
If no transaction currently exists, it runs in a non transactional manner

5,NOT_SUPPORTED

Run as non transactional
If a transaction currently exists, suspend the current transaction

6,MANDATORY

If a transaction currently exists, it runs in the current transaction
If there is no transaction at present, an exception is thrown, that is, the parent method must have a transaction

7,NEVER

Run in non transactional mode. If there is a transaction currently, an exception will be thrown, that is, the parent method must have no transaction

3, Other parameters

1,isolation


A. Dirty read: transaction a reads the data updated by transaction B, and then transaction B rolls back the operation. Then the data read by transaction a is dirty data

B. Non repeatable reading: transaction A reads the same data multiple times, and transaction B updates and commits the data during the multiple reading of transaction A, resulting in inconsistent results when transaction A reads the same data multiple times.

C. Unreal reading: system administrator A changed the scores of all students in the database from specific scores to ABCDE level, but system administrator B inserted A record of specific scores at this time. When system administrator A found that another record had not been changed after the change, it was like an illusion. This is called Unreal reading.

Summary: non repeatable reading and phantom reading are easy to be confused. Non repeatable reading focuses on modification, and phantom reading focuses on addition or deletion. To solve the problem of non repeatable reading, you only need to lock the rows that meet the conditions, and to solve the phantom reading, you need to lock the table

2,readOnly

Whether it is a read-only transaction. The default is false

3,rollbackFor

Specifies the exception type of rollback. When encountered, it must be rolled back
For example:

rollbackFor = {NullPointerException.class,ArrayIndexOutOfBoundsException.class}

4,rollbackForClassName

Specifies the name of the exception class to be rolled back. It must be rolled back when encountered
For example:

rollbackForClassName = {"NullPointerException","ArrayIndexOutOfBoundsException"}

5,noRollbackFor

Specifies the exception type that does not need to be rolled back. When encountered, it does not need to be rolled back
For example:

noRollbackFor = {NullPointerException.class,ArrayIndexOutOfBoundsException.class}

6,noRollbackForClassName

Specify the exception class name that does not need to be rolled back. When encountered, it does not need to be rolled back
For example:

noRollbackForClassName= {"NullPointerException","ArrayIndexOutOfBoundsException"}

7,timeout

Transaction timeout

Reference articles

Keywords: Java Spring

Added by mfalomir on Mon, 27 Sep 2021 22:32:51 +0300