1. What is a business?
In a series of operations on the database, ensure that they succeed or fail at the same time, and there can be no partial success or partial failure. This series of operations is called database transactions.
2. Characteristics of transactions
Atomicity: refers to that a transaction is an inseparable work unit, and the operations of the transaction either occur or do not occur.
Consistency: the integrity of data before and after the transaction must be consistent.
Isolation: when multiple users access the database concurrently, the transactions of one user cannot be disturbed by the transactions of other users, and the data of multiple concurrent users are isolated from each other.
Persistence: once a transaction is committed, its changes to the data in the database are permanent. Then, even if the database fails, it should not have any impact on it.
3. Isolation level of transactions
When using java operation, set the isolation level from high to low as follows:
Serializable: it can avoid dirty reading, non repeatable reading and virtual reading.
Repeatable read: it can avoid dirty reading and non repeatable reading. (can be read repeatedly)
Read committed: to avoid dirty reading. (read submitted).
Read uncommitted: the lowest level. The above conditions are not guaranteed (read uncommitted).
Dirty read: refers to that one transaction reads uncommitted data from another transaction.
Non repeatable reading: read a row of data in a table within a transaction, and the reading results are different multiple times (one transaction reads the data submitted by another transaction).
Virtual read: refers to the data inserted by other transactions read in one transaction, resulting in inconsistent data.
Note: the default transaction level of most databases is Read committed, such as SqlServer Oracle. The default isolation level of MySQL is Repeatable read.
4. Transaction control manager of spring
Transaction provided by Spring: platform transaction manager, which provides three methods
getTransaction(TransactionDefinition) -- get a transaction management object
Transaction definition: transaction descriptor [simply set the transaction to be operated]
commit() commit transaction
rollback() transaction rollback
According to the different frameworks used by dao layer (persistence layer / data access layer), the main implementation classes of PlatformTransactionManager are roughly as follows:
1. When JDBC and MyBatis are used for data persistence: DataSourceTransactionManager class
2. When Hibernate is used for data persistence: HibernateTransactionManager class
5. Specific transaction management operations [declarative transaction management]
Declarative transaction management -- without writing java code, set transaction management through configuration in Spring configuration file.
1). Transaction management operation based on xml
(1) Download dependent packages
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.5.RELEASE</version> </dependency> <!-- spring-jdbc --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.5.RELEASE</version> </dependency> <!-- spring_tx --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.1.5.RELEASE</version> </dependency> <!-- MyBatis rely on --> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!-- mybatis-spring Integration package --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- mysql Database driven --> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--druid Ali's connection pool--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.7</version> </dependency>
(2). Create mapper interface
import java.util.HashMap; public interface TransferMapper { //Add money public void addMony(HashMap<String,Object> parms); //Reduce money public void lessMony(HashMap<String,Object> parms); }
(3) Configuration mapping file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.wangxing.demo1.mapper.TransferMapper"> <update id="addMoney" parameterType="java.util.HashMap"> update t_account set money=money+#{mymoney} where user_name=#{myname}; </update> <update id="lessMoney" parameterType="java.util.HashMap"> update t_account set money=money-#{mymoney} where user_name=#{myname}; </update> </mapper>
(4) Writing Spring configuration files
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- Configure automatic scanning package --> <context:component-scan base-package="com.demo.service"></context:component-scan> <!--Read resource file--> <context:property-placeholder location="classpath:db.properties"></context:property-placeholder> <!-- Configure data source --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${mydriver}"></property> <property name="url" value="${myurl}"></property> <property name="username" value="${myusername}"></property> <property name="password" value="${mypassword}"></property> </bean> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mapperLocations" value="classpath:TransferMapper.xml"></property> </bean> <!-- Configure the scanning database access interface and create database access objects --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.demo.mapper"></property> </bean> <!--Transaction configuration--> <!-- Transaction configuration--> <!-- 1.Create transaction object--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- Configure data source --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2 Create transaction --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="transfer"/> </tx:attributes> </tx:advice> <!-- adopt aop Apply the above created things to the specified business methods --> <aop:config> <aop:pointcut id="point" expression="execution(* com.demo.service.TransferService.transfer())"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="point"></aop:advisor> </aop:config> </beans>
(5) Create business processing class
import com.demo.mapper.TransferMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; @Service public class TransferService { @Autowired private TransferMapper transferMapper; public void transfer(){ HashMap<String, Object> liuneng; liuneng = new HashMap<String, Object>(); liuneng.put("name", "Zhang San"); liuneng.put("age", 100); int i = 1/0; transferMapper.addMony(liuneng); HashMap<String, Object> zhaosi = new HashMap<String, Object>(); zhaosi.put("name", "Li Si"); zhaosi.put("age", 100); transferMapper.lessMony(zhaosi); System.out.println("Transaction added successfully"); } }
(6) configuration database link resource file
mydriver = com.mysql.jdbc.Driver myurl = jdbc:mysql://127.0.0.1:3306/test myusername = root mypassword = 123456
(7) Testing
import com.demo.service.TransferService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestMain { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContextTwo.xml"); TransferService transferService = ac.getBean("transferService", TransferService.class); transferService.transfer(); } }
2). Annotation based transaction management operations
The steps are the same as above and need to be changed (4) and (5)
(4) Spring 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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.demo.service"></context:component-scan> <context:property-placeholder location="classpath:db.properties"></context:property-placeholder> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${mydriver}"></property> <property name="url" value="${myurl}"></property> <property name="username" value="${myusername}"></property> <property name="password" value="${mypassword}"></property> </bean> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mapperLocations" value="classpath:TransferMapper.xml"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.demo.mapper"></property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven> </beans>
(5) Add annotation to Service
import com.demo.mapper.TransferMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; @Service public class TransferService { @Autowired private TransferMapper transferMapper; @Transactional public void transfer(){ HashMap<String, Object> liuneng; liuneng = new HashMap<String, Object>(); liuneng.put("name", "Zhang San"); liuneng.put("age", 100); int i = 1/0; transferMapper.addMony(liuneng); HashMap<String, Object> zhaosi = new HashMap<String, Object>(); zhaosi.put("name", "Li Si"); zhaosi.put("age", 100); transferMapper.lessMony(zhaosi); System.out.println("Transaction added successfully"); } }
Helpless from not strong enough