Understand spring transactions in depth

  • 2021-08-31 08:14:45
  • OfStack

Transaction introduction

1 Transactions either succeed or fail at the same time

Characteristic

An Atomic atomic transaction is a unit of work consisting of one or more activities. Atomicity ensures that all operations in a transaction occur or do not occur at all When Consistent1 is completed, the system must ensure that the business it models is in a 1 state Isolated Isolated transactions allow multiple users to manipulate data without entangling each user's operations with other users Durable Persistence 1 Once the transaction is completed, the result of the transaction should be persisted

Transaction isolation level

DEFAULT uses the default isolation level of the underlying database READ_UNCOMMITTED (Read Uncommitted Data) allows transactions to read data that has not been committed by other parallel transactions. Dirty read, unrepeatable read and phantom read problems exist READ_COMMITTED (Read Committed Data) allows transactions to read only data committed by other parallel transactions, avoiding dirty reads, but non-repeatable and phantom reads still exist REPEATABLE_READ (Repeatable Read) ensures that a transaction can read the same value from one field more than once, preventing other transactions from updating the field during the duration of the transaction, avoiding dirty and non-repeatable readings, but phantom readings still exist (Mysql default transaction isolation level) SERIALIZABLE (Serialization) ensures that a transaction can read the same row from a table, prohibits other transactions from inserting, updating, and deleting the table during the duration of the transaction, all concurrency problems are avoided, but performance is poor

Communication behavior

PROPAGATION_REQUIRED supports the current transaction. If there is no transaction at present, a new transaction will be created PROPAGATION_SUPPORTS supports current transactions, and if there is no transaction at present, it will be executed in a non-transactional manner PROPAGATION_MANDATORY supports current transactions and throws an exception if there is no current transaction PROPAGATION_REQUIRED_NEW Create a new transaction and suspend the current transaction if it currently exists PROPAGATION_NOT_SUPPORTED Performs operations in a non-transactional manner, suspending the current transaction if it currently exists PROPAGATION_NEVER Performs operations in a non-transactional manner and throws an exception if a transaction currently exists PROPAGATION_NESTED Executes within a nested transaction if a transaction currently exists, or creates a new transaction if no transaction currently exists

Read-only

Transaction only reads

readOnly=true Tells spring that the current transaction will only perform read operations, not modify operations, which can help the database engine tune

Note: If it is set to read-only, do not modify the data in the transaction. When using read-only operation, spring will not lock. If the data is modified, there will be problems

Transaction timeout

If the transaction time is too long, roll back

Rollback rule

rollback-for means that transactions should be rolled back without committing for those checked exceptions (default spring rolls back for all runtime exceptions)

no-rollback-for means that the transaction continues without rollback for those exceptions

Use of transactions


create table user(
 id int primary key AUTO_INCREMENT,
 name varchar(20) not null,
 account double 
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 insert into user (name,account) values(' Zhang 3',1000);
 insert into user (name,account) values(' Li 4',1000);

<!--  Affairs  -->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
 <version>4.3.29.RELEASE</version>
</dependency>

<!--  Transaction Manager and Data Source  -->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>4.3.29.RELEASE</version>
</dependency>

<!-- mysql Drive  -->
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>5.1.48</version>
</dependency>

Use annotations

The data source in spring is used here


<!--  Data source  -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
 <property name="username" value="root" />
 <property name="password" value="123456" />
</bean>

<!--  Transaction Manager  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>

<!--  Enable transaction annotation  -->
<tx:annotation-driven transaction-manager="transactionManager"/>

Of course, because the annotations are used, don't forget to scan the components


<context:component-scan base-package="com.zhanghe.study.spring4.beans.tx"/>

You can then configure @ Transactional on the method that you want to guarantee the transaction and the corresponding transaction isolation level (isolation), transaction propagation behavior (propagation), which exceptions to roll back (rollbackFor), and no rollback (noRollbackFor) on this annotation. By default, roll back runtime exceptions

Using XML


<!--  Data source  -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
 <property name="username" value="root" />
 <property name="password" value="123456" />
</bean>

<!--  Transaction Manager  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>

<!--  Use xml Configuring transaction properties  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
 <!--  Specify a specific transaction property based on the method name  -->
 <tx:method name="get*" read-only="true"/>
 <tx:method name="find*" read-only="true"/>
 <tx:method name="save*" propagation="REQUIRED"/>
 </tx:attributes>
</tx:advice>

<!--  Use transaction pointcuts to associate transaction pointcuts with transaction attributes  -->
<aop:config>
 <aop:pointcut id="pointCut" expression="execution(* com.zhanghe.study.spring4.beans.tx.UserService.*(..))"/>
 <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>

Related articles: