Spring (transaction)

1. What transaction? In
a series of operations on the database, it is guaranteed to succeed or fail at the same time. There must be no partial success and partial failure. And these series of operations are called database transactions.
2. The characteristics
of transactions Database transactions have four major characteristics:
Atomicity: refers to the transaction is an indivisible unit of work, transaction operations either occur or do not occur.
Consistency: the integrity of the data before and after the transaction must be consistent .
Isolation: When multiple users access the database concurrently, the transactions of one user cannot be interfered by the transactions of other users, and the data between multiple concurrent users must be isolated from each other.
Persistence: Once a transaction is committed, its changes to the data in the database are permanent, and then even if the database fails, it should not be affected in any way. Referred to as ACID. Among them, isolation is the most important.
3. The isolation level of the transaction
If isolation is not considered, the following problems may arise:
Dirty read: Refers to a transaction that reads uncommitted data from another transaction.
Non-repeatable read: read a row of data in the table within one transaction, and the results of multiple reads are different (data submitted by another transaction read by one transaction)
virtual read (phantom read): time refers to read within one transaction The data inserted by other transactions resulted in inconsistent reading before and after.
When using Java operations, the isolation levels set from high to low are:
Serializable: to avoid dirty reads, non-repeatable reads, and virtual reads.
Repeatable read: It can avoid dirty reads and non-repeatable reads. (Repeatable read)
Read committed: to avoid the occurrence of dirty reads. (
Read uncommitted ) Read uncommitted: the lowest level, the above conditions are not guaranteed. (Read uncommitted)
It is worth mentioning that the default transaction isolation level of most databases is Read committed, such as Sql Server and Oracle. Mysql's default isolation level is Repeatable read.
Java's JDBC isolation level operations on transactions
In Java, the isolation level of the database can be set through the Connection object, and transactions can be controlled.
Constants for setting the isolation level supported in Connection:

Set the isolation level of the database:

E.g:

Connection conn=DBConnection.getConnection();
//设置事物的隔离级别
conn.setTransactionIsolation(Connection.TRANSANCTION_READ_COMMITTED);

Get the isolation level of the database:

Java's JDBC operations on transactions
1. Before operating the database, cancel the automatic commit of the database:

2、当数据库出现问题的时候,回滚事务

3、当数据库操作一切都正常,提交事务

4.
Spring 's transaction manager Spring provides transaction control interface: PlatformTransactionManager provides three methods:
Insert picture description here

According to the different frameworks used by the dao layer (persistence layer/data access layer), the main implementation classes of PlatformTransactionManager are roughly as follows:
DataSourceTransactionManager: suitable for data persistence operations using JDBC and MyBatis.
HibernateTransactionManager: Applicable to the use of Hibernate for data persistence operations.
Insert picture description here

5. Specific transaction management operations [Declarative transaction management]
1. Transaction management operations based on xml mode
1. Create t_account account tables in the database, simulate transfers, and demonstrate spring transaction control.

create table t_account(
account_id int primary key auto_increment,
user_name varchar(20),
money int
);
insert  into  t_account values(null,'刘能',10000);
insert  into  t_account values(null,'赵四',10000);

Insert picture description here

2. Create the project to complete the project structure, import dependencies

<!-- 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依赖 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.6</version>
</dependency>
<!-- mybatis-spring 整合包 -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.3.1</version>
</dependency>
<!-- mysql数据库驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
</dependency>
<!--druid 阿里的连接池-->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.7</version>
</dependency>

3.创建数据访问接口
package com.wangxing.spring.mapper;
import java.util.Map;
//数据访问接口
public interface TransferMapper {
    // 加钱
    public void addMoney(Map param);
    // 减钱
    public void lessMoney(Map  param);
}

4. Create the SQL mapping file corresponding to the data access interface

<?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.spring.mapper.TransferMapper">
    <update id="addMoney" parameterType="hashMap">
        update t_account set money = money + #{number} where user_name = #{username}
    </update>
    <update id="lessMoney" parameterType="hashMap">
        update t_account set money = money - #{number} where user_name = #{username}
    </update>
</mapper>
5.创建业务访问类,并提供具体的业务方法
package com.wangxing.spring.service;

import com.wangxing.spring.mapper.TransferMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service("transferService")
public class TransferService {
    @Autowired
    private TransferMapper transferMapper;
    /**
     * 转账方法
     * @throws Exception
     */
    public void transfer()throws Exception{
        Map<String,Object> liuneng=new HashMap<String,Object>();
        liuneng.put("username","刘能");
        liuneng.put("number",1000);
        transferMapper.lessMoney(liuneng);
        //int a=10/0;
        Map<String,Object> zhaosi=new HashMap<String,Object>();
        zhaosi.put("username","赵四");
        zhaosi.put("number",1000);
        transferMapper.addMoney(zhaosi);
    }
}

6. Create a database connection file [mydata.properties]

mydriver = com.mysql.jdbc.Driver
myurl = jdbc:mysql://127.0.0.1:3306/test
myusername = root
mypassword = 123456

7. Create 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">
    <!-- 配置自动扫描service包 -->
    <context:component-scan base-package="com.wangxing.spring.service"></context:component-scan>
    <!--配置加载mydata.properties-->
    <context:property-placeholder location="classpath:mydata.properties"></context:property-placeholder>
    <!--配置数据源-->
    <!-- com.alibaba.druid.pool.DruidDataSource-->
    <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>
    <!-- 配置SqlSessionFactory -->
    <!-- org.mybatis.spring.SqlSessionFactoryBean-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
        <!--注入sql映射文件路径-->
        <property name="mapperLocations" value="classpath:mapper/TransferMapper.xml"></property>
    </bean>
    <!--配置扫描数据库访问接口包,创建数据库访问接口对象-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wangxing.spring.mapper"></property>
    </bean>
    <!-- 配置事務管理 -->
    <!--1.创建事务管理器对象-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--2.创建事务-->
    <tx:advice id="txAdvice1" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer"/>
        </tx:attributes>
    </tx:advice>
    <!--3.通过aop将上面创建好的事物,作用到指定的业务方法中 -->
    <aop:config>
        <aop:pointcut id="point1" expression="execution(* com.wangxing.spring.service.TransferService.transfer())"/>
        <aop:advisor advice-ref="txAdvice1" pointcut-ref="point1"></aop:advisor>
    </aop:config>
</beans>

2. Transaction management operations based on annotation methods
1. Add @Transactional to the business class or business processing method that needs to use the transaction. @Transactional
configuration on the business class @Transactional means that all methods in the current business class exist in the transaction processing
business processing method. Configure @ Transactional means that only transaction processing exists on the current business processing method

package com.wangxing.spring.service;

import com.wangxing.spring.mapper.TransferMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

@Service("transferService")
@Transactional
public class TransferService {
    @Autowired
    private TransferMapper transferMapper;
    /**
     * 转账方法
     * @throws Exception
     */
    public void transfer()throws Exception{
        Map<String,Object> liuneng=new HashMap<String,Object>();
        liuneng.put("username","刘能");
        liuneng.put("number",1000);
        transferMapper.lessMoney(liuneng);
        int a=10/0;
        Map<String,Object> zhaosi=new HashMap<String,Object>();
        zhaosi.put("username","赵四");
        zhaosi.put("number",1000);
        transferMapper.addMoney(zhaosi);
    }
}

2. Turn on transaction annotations in the 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">
    <!-- 配置自动扫描service包 -->
    <context:component-scan base-package="com.wangxing.spring.service"></context:component-scan>
    <!--配置加载mydata.properties-->
    <context:property-placeholder location="classpath:mydata.properties"></context:property-placeholder>
    <!--配置数据源-->
    <!-- com.alibaba.druid.pool.DruidDataSource-->
    <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>
    <!-- 配置SqlSessionFactory -->
    <!-- org.mybatis.spring.SqlSessionFactoryBean-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
        <!--注入sql映射文件路径-->
        <property name="mapperLocations" value="classpath:mapper/TransferMapper.xml"></property>
    </bean>
    <!--配置扫描数据库访问接口包,创建数据库访问接口对象-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wangxing.spring.mapper"></property>
    </bean>
    <!-- 配置事務管理 -->
    <!--1.创建事务管理器对象-->
    <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>-->
    <!-- 由于tx:annotation-driven的配置事务管理器的属性transaction-manager的默认值是transactionManager,
         我们创建的事务管理器对象的名称也是transactionManager,因此在配置tx:annotation-driven元素时
         transaction-manager属性是不用写
    -->
    <tx:annotation-driven></tx:annotation-driven>
</beans>

Guess you like

Origin blog.csdn.net/guoguo0717/article/details/110064389