affairs
1. What is the business
Transaction is the most basic unit of database operation.
Typical Case: Bank Transfer
2. Four Characteristics of Transactions (ACID)
- atomicity
- consistency
- isolation
- Persistence
Declarative Transaction Management
- Annotation-based
- XML-based configuration file
Declarative transaction management in spring, using AOP principle at the bottom
Transaction Operations (Declarative Transactions)
@Transactional parameter explanation
- Propagation: Propagation Behavior
When a transaction method is called by another transaction method, you must specify how the transaction should propagate. For example: a method may continue to run in an existing transaction, or it may start a new transaction and run in its own transaction.
spread behavior | meaning |
---|---|
PROPAGATION_REQUIRED | If there is no current transaction, a new transaction is created, and if a transaction already exists, it is added to this transaction. This is the most common choice. |
PROPAGATION_SUPPORTS | Support the current transaction, if there is no current transaction, it will be executed in a non-transactional mode. |
PROPAGATION_MANDATORY | Indicates that the method must be run in a transaction, if the current transaction does not exist, an exception will be thrown |
PROPAGATION_REQUIRED_NEW | Indicates that the current method must run in its own transaction. A new transaction will be started. If there is a current transaction, the current transaction will be suspended during the execution of this method. |
PROPAGATION_NOT_SUPPORTED | Indicates that the method should not be run in a transaction. If there is currently a transaction, suspend the current transaction. |
PROPAGATION_NEVER | Indicates that the current method should not run in a transaction context. Throws an exception if a transaction is currently running |
PROPAGATION_NESTED | If a transaction currently exists, execute within a nested transaction. If there are no current transactions, do something similar to PROPAGATION_REQUIRED. |
- ioslation: transaction isolation
name | describe |
---|---|
dirty read | Transaction A reads the data updated by transaction B, and then B rolls back the operation, so the data read by A is dirty data. |
non-repeatable read | Transaction A reads the same data multiple times. In , the data is updated and committed, resulting in inconsistent results when transaction A reads the same data multiple times. |
hallucinations | System administrator A changed the grades of all students in the database from specific scores to ABCDE grades, but system administrator B inserted a record with specific scores at this time. If you change it, it's like hallucination. This is called hallucination. |
Non-repeatable reads and phantom reads are easily confused. Non-repeatable reads focus on modification, while phantom reads focus on additions or deletions. To solve the problem of non-repeatable read, you only need to lock the rows that meet the conditions, and to solve the phantom read, you need to lock the table
- timeout: timeout event
The transaction is committed within a certain period of time, and if it is not committed, it will be rolled back
The default value is -1, the set time is calculated in seconds
- readOnly: read-only
The default is false, which means that you can query or add, modify, and delete
- rollbackFor: rollback
Set which exceptions occur for transaction rollback
- noRollbackFor: do not roll back
Set which exceptions are not rolled back
Related code
1. Configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/test3"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="datasource"></property> </bean> <!-- Annotation Scan--> <context:component-scan base-package="com.company.Tx"></context:component-scan> <!-- Create transaction manager--> <bean id="Transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean> <bean id="sMDao" class="com.company.Tx.Dao.SMDao" abstract="true"></bean> <bean id="sMDaoImpl" class="com.company.Tx.Dao.SMDaoImpl" autowire="byType"></bean> <bean id="sMService" class="com.company.Tx.Service.SMService" autowire="byType"></bean> <!--Configure notifications--> <tx:advice id="cqw" transaction-manager="Transaction"> <tx:attributes> <tx:method name="playMoney" propagation="REQUIRED" isolation="REPEATABLE_READ"/> </tx:attributes> </tx:advice> <aop:config> <!-- Configure pointcut--> <aop:pointcut id="pt" expression="execution(* com.company.Tx.Service.SMService.*(..))"/> <!-- Configure Aspects--> <aop:advisor advice-ref="cqw" pointcut-ref="pt"></aop:advisor> </aop:config> <!-- Open transaction manager--> <!-- <tx:annotation-driven transaction-manager="Transaction"></tx:annotation-driven>--> </beans>
2. Related Dao and Service operation classes
- SMDao
package com.company.Tx.Dao; public interface SMDao { public void add(); public void reduce(); }
- SMDaoImpl
package com.company.Tx.Dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; public class SMDaoImpl implements SMDao{ @Autowired JdbcTemplate jdbcTemplate; @Override public void add() { String sqlAdd="update account set money=money-100 where name=?"; Object[] objects={"cqw"}; final int update = jdbcTemplate.update(sqlAdd, objects); System.out.println("cqw $100 less result::"+update); } @Override public void reduce() { String sqlAdd="update account set money=money+100 where name=?"; Object[] objects={"sm"}; final int update = jdbcTemplate.update(sqlAdd, objects); System.out.println("SM get a result of 100 yuan::"+update); } }
- SMService
package com.company.Tx.Service; import com.company.Tx.Dao.SMDao; public class SMService { private SMDao sMDao; public void setsMDao(SMDao sMDao) { this.sMDao = sMDao; } public void playMoney(){ sMDao.add(); int a=10/0; sMDao.reduce(); } }
- TestDemo
@Test public void Test06(){ ApplicationContext context = new ClassPathXmlApplicationContext("com/company/beanTX.xml"); final SMService sMService = context.getBean("sMService", SMService.class); sMService.playMoney(); }
- Result (data rollback, data unchanged)
cqw Result of 100 yuan less::1 java.lang.ArithmeticException: / by zero at com.company.Tx.Service.SMService.playMoney(SMService.java:21)