Primavera (transacción)

1. ¿Qué transacción? En
una serie de operaciones en la base de datos, se garantiza que tendrá éxito o fracasará al mismo tiempo. No debe haber un éxito parcial ni un fracaso parcial. Y esta serie de operaciones se denominan transacciones de base de datos.
2. Las características
de las transacciones Las transacciones de la base de datos tienen cuatro características principales:
Atomicidad: se refiere a que la transacción es una unidad de trabajo indivisible, las operaciones de transacción ocurren o no ocurren.
Consistencia: la integridad de los datos antes y después de la transacción debe ser consistente .
Aislamiento: cuando varios usuarios acceden a la base de datos al mismo tiempo, las transacciones de un usuario no pueden verse interferidas por las transacciones de otros usuarios, y los datos entre varios usuarios simultáneos deben aislarse entre sí.
Persistencia: una vez que se confirma una transacción, sus cambios en los datos de la base de datos son permanentes, y luego, incluso si la base de datos falla, no debería verse afectada de ninguna manera. Conocido como ACID. Entre ellos, el aislamiento es el más importante.
3. El nivel de aislamiento de la transacción
Si no se considera el aislamiento , pueden surgir los siguientes problemas:
Lectura sucia: se refiere a una transacción que lee datos no confirmados de otra transacción.
Lectura no repetible: lee una fila de datos en la tabla dentro de una transacción, y los resultados de múltiples lecturas son diferentes (datos enviados por otra transacción leídos por una transacción)
lectura virtual (lectura fantasma): el tiempo se refiere a la lectura dentro de una transacción Los datos insertados por otras transacciones resultaron en lecturas inconsistentes antes y después.
Cuando se utilizan operaciones Java, los niveles de aislamiento establecidos de mayor a menor son:
Serializable: para evitar lecturas sucias, lecturas no repetibles y lecturas virtuales.
Lectura repetible: puede evitar lecturas sucias y lecturas no repetibles. (Lectura repetible)
Lectura comprometida: para evitar la ocurrencia de lecturas sucias. (
Lectura no confirmada ) Lectura no confirmada: el nivel más bajo, las condiciones anteriores no están garantizadas. (Leer no comprometido)
Vale la pena mencionar que el nivel de aislamiento de transacciones predeterminado de la mayoría de las bases de datos es Lectura confirmada, como Sql Server y Oracle. El nivel de aislamiento predeterminado de Mysql es Lectura repetible.
Operaciones de nivel de aislamiento JDBC de Java en transacciones
En Java, el nivel de aislamiento de la base de datos se puede establecer a través del objeto Connection y las transacciones se pueden controlar.
Constantes para establecer el nivel de aislamiento admitido en Connection:

Establezca el nivel de aislamiento de la base de datos:

P.ej:

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

Obtenga el nivel de aislamiento de la base de datos:

Operaciones JDBC de Java en transacciones
1. Antes de operar la base de datos, cancele la confirmación automática de la base de datos:

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

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

4. Administrador de transacciones de
Spring Spring proporciona una interfaz de control de transacciones: PlatformTransactionManager proporciona tres métodos:
Inserte la descripción de la imagen aquí

De acuerdo con los diferentes frameworks usados ​​por la capa dao (capa de persistencia / capa de acceso a datos), las principales clases de implementación de PlatformTransactionManager son aproximadamente las siguientes:
DataSourceTransactionManager: adecuado para operaciones de persistencia de datos usando JDBC y MyBatis.
HibernateTransactionManager: Aplicable al uso de Hibernate para operaciones de persistencia de datos.
Inserte la descripción de la imagen aquí

5. Operaciones específicas de administración de transacciones [Administración declarativa de transacciones]
1. Operaciones de administración de transacciones basadas en el modo xml
1. Cree tablas de cuentas t_account en la base de datos, simule transferencias y demuestre el control de transacciones Spring.

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);

Inserte la descripción de la imagen aquí

2. Cree el proyecto para completar la estructura del proyecto, importe las dependencias

<!-- 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. Cree el archivo de mapeo SQL correspondiente a la interfaz de acceso a datos.

<?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. Cree un archivo de conexión de base de datos [mydata.properties]

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

7. Cree el archivo de configuración de Spring

<?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. Operaciones de administración de transacciones basadas en métodos de anotación
1. Agregue @Transactional a la clase de negocios o método de procesamiento comercial que necesita usar la transacción. La
configuración de @Transactional en la clase de negocios @Transactional significa que todos los métodos en la clase de negocios actual existen en el procesamiento de transacciones
método de procesamiento comercial. Configurar @ Transaccional significa que solo existe procesamiento de transacciones en el método de procesamiento comercial actual

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. Active las anotaciones de transacciones en el archivo de configuración de Spring.

<?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>

Supongo que te gusta

Origin blog.csdn.net/guoguo0717/article/details/110064389
Recomendado
Clasificación