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 persistedTransaction 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 poorCommunication 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 existsRead-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&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&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>