Capítulo 44 de Spring's Road to God: explicación detallada de las transacciones declarativas de Spring (@Transactional)

Capítulo 44 de Spring's Road to God: explicación detallada de las transacciones declarativas de Spring (@Transactional)

Hay dos usos de las transacciones de primavera: transacciones programáticas y transacciones declarativas .

Las transacciones programáticas se introdujeron en el artículo anterior . Si no está familiarizado con esto, se recomienda ver primero el uso de las transacciones programáticas.

Este artículo presenta principalmente el uso de transacciones declarativas. Básicamente usamos transacciones declarativas en nuestro trabajo, por lo que este artículo es más importante. Le sugiero que se anime y comience oficialmente.

¿Qué son las transacciones declarativas?

La llamada transacción declarativa es para decirle a Spring a través de la configuración, como el archivo de configuración (xml) o la anotación, qué métodos necesitan Spring para ayudar a administrar la transacción, y luego los desarrolladores solo deben prestar atención al código comercial, y Spring automáticamente ayuda con la transacción Nosotros controlamos.

Por ejemplo, en la forma de anotación@Transaction , solo necesita agregar una anotación en el método, luego Spring iniciará automáticamente una transacción antes de que se ejecute el método, y después de que se ejecute el método, enviará o revertirá automáticamente la transacción, y no hay código relacionado con la transacción dentro del método, que es muy especial para usar

@Transaction
public void insert(String userName){
    
    
    this.jdbcTemplate.update("insert into t_user (name) values (?)", userName);
}

Dos implementaciones de transacciones declarativas

  1. La forma de los archivos de configuración , es decir, para realizar una configuración unificada en el archivo spring xml, los desarrolladores básicamente no necesitan prestar atención a los asuntos de transacciones, y no hay necesidad de preocuparse por ningún código relacionado con transacciones en el código, y todo se maneja por resorte.
  2. Para la forma de anotación , solo necesita agregar la anotación @Transaction en el método que necesita Spring para ayudar a administrar los asuntos. La forma de anotación es relativamente más concisa y los desarrolladores deben configurarla ellos mismos. Es posible que algunos estudiantes no entiendan Spring. También familiar, por lo que existe un cierto riesgo al configurar esto, solo haga una buena revisión del código.

La forma de configurar los archivos no se menciona aquí, y se usa relativamente poco. Principalmente dominamos cómo usar las anotaciones, y eso es todo.

5 pasos para la anotación de transacciones declarativas

1. Habilite la función de gestión de transacciones basada en anotaciones de Spring

@EnableTransactionManagementAgregar anotaciones a la clase de configuración de primavera

@EnableTransactionManagement
public class MainConfig4 {
    
    
}

Presente brevemente el principio: cuando se inicia el contenedor de primavera, encuentra la anotación @EnableTransactionManagement. En este momento, interceptará la creación de todos los beans y escaneará para ver si hay una anotación @Transaction en el bean (clase o padre). clase, interfaz o método) Esta anotación está disponible), si existe esta anotación, Spring generará un objeto proxy para el bean a través de aop, y se agregará un interceptor al objeto proxy, que interceptará la ejecución del método público en el bean, e iniciará la transacción antes de que se ejecute el método, confirmará o revertirá la transacción después de que se ejecute el método. Habrá un artículo dedicado para mostrarle el código fuente de esta pieza más adelante.

Si está interesado, puede leer primero el código fuente, principalmente porque el siguiente método

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

Echemos un vistazo al código fuente de EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
    
    

 /**
  * spring是通过aop的方式对bean创建代理对象来实现事务管理的
  * 创建代理对象有2种方式,jdk动态代理和cglib代理
  * proxyTargetClass:为true的时候,就是强制使用cglib来创建代理
  */
 boolean proxyTargetClass() default false;

 /**
  * 用来指定事务拦截器的顺序
  * 我们知道一个方法上可以添加很多拦截器,拦截器是可以指定顺序的
  * 比如你可以自定义一些拦截器,放在事务拦截器之前或者之后执行,就可以通过order来控制
  */
 int order() default Ordered.LOWEST_PRECEDENCE;
}

2. Definir el administrador de transacciones

Si Spring administra la transacción, debe crear uno o más administradores de transacciones.Estos administradores son responsables de administrar transacciones específicas, como iniciar una transacción, confirmar una transacción y revertir una transacción.

Spring usa la interfaz PlatformTransactionManager para representar el administrador de transacciones.

Múltiples clases de implementación de PlatformTransactionManager para manejar diferentes entornos

[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente (img-NIJYdB5Q-1684550694441)(%E6%96%B0%E5%BB%BA% E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113416897-1649199944.png)]

JpaTransactionManager : si usa jpa para operar db, necesita usar este administrador para ayudarlo a controlar las transacciones.

DataSourceTransactionManager : si usa el método para especificar la fuente de datos, como operar la base de datos usando: JdbcTemplate, mybatis, ibatis, entonces necesita usar este administrador para ayudarlo a controlar la transacción.

HibernateTransactionManager : si usa hibernate para operar db, entonces necesita usar este administrador para ayudarlo a controlar las transacciones.

JtaTransactionManager : si usa jta en Java para operar db, esta suele ser una transacción distribuida, y necesita usar este administrador para controlar la transacción.

Por ejemplo: usamos mybatis o jdbctemplate, luego definimos un administrador de transacciones de la siguiente manera.

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    
    
    return new DataSourceTransactionManager(dataSource);
}

3. Agregue la anotación @Transaction al destino que necesita usar la transacción

  • @Transaction se coloca en la interfaz , luego todos los públicos en la clase de implementación de la interfaz se agregarán automáticamente con transacciones en primavera
  • Ponga @Transaction en la clase , luego todos los métodos publicc en la clase actual y sus subclases infinitas se agregarán automáticamente con transacciones en primavera
  • @Transaction se coloca en el método público, luego el método se agregará automáticamente a la transacción en primavera
  • Nota: @Transaction solo es válido para métodos públicos

Echemos un vistazo al código fuente de @Transactional:

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    
    

    /**
     * 指定事务管理器的bean名称,如果容器中有多事务管理器PlatformTransactionManager,
     * 那么你得告诉spring,当前配置需要使用哪个事务管理器
     */
    @AliasFor("transactionManager")
    String value() default "";

    /**
     * 同value,value和transactionManager选配一个就行,也可以为空,如果为空,默认会从容器中按照类型查找一个事务管理器bean
     */
    @AliasFor("value")
    String transactionManager() default "";

    /**
     * 事务的传播属性
     */
    Propagation propagation() default Propagation.REQUIRED;

    /**
     * 事务的隔离级别,就是制定数据库的隔离级别,数据库隔离级别大家知道么?不知道的可以去补一下
     */
    Isolation isolation() default Isolation.DEFAULT;

    /**
     * 事务执行的超时时间(秒),执行一个方法,比如有问题,那我不可能等你一天吧,可能最多我只能等你10秒
     * 10秒后,还没有执行完毕,就弹出一个超时异常吧
     */
    int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

    /**
     * 是否是只读事务,比如某个方法中只有查询操作,我们可以指定事务是只读的
     * 设置了这个参数,可能数据库会做一些性能优化,提升查询速度
     */
    boolean readOnly() default false;

    /**
     * 定义零(0)个或更多异常类,这些异常类必须是Throwable的子类,当方法抛出这些异常及其子类异常的时候,spring会让事务回滚
     * 如果不配做,那么默认会在 RuntimeException 或者 Error 情况下,事务才会回滚 
     */
    Class<? extends Throwable>[] rollbackFor() default {
    
    };

    /**
     * 和 rollbackFor 作用一样,只是这个地方使用的是类名
     */
    String[] rollbackForClassName() default {
    
    };

    /**
     * 定义零(0)个或更多异常类,这些异常类必须是Throwable的子类,当方法抛出这些异常的时候,事务不会回滚
     */
    Class<? extends Throwable>[] noRollbackFor() default {
    
    };

    /**
     * 和 noRollbackFor 作用一样,只是这个地方使用的是类名
     */
    String[] noRollbackForClassName() default {
    
    };

}

Introducción de parámetros

parámetro describir
valor Especifique el nombre del bean del administrador de transacciones.Si hay varios administradores de transacciones PlatformTransactionManager en el contenedor, entonces debe decirle a Spring qué administrador de transacciones necesita usar la configuración actual
administrador de transacciones Simplemente elija uno del mismo valor, valor y TransactionManager, o puede estar vacío, si está vacío, buscará un bean del administrador de transacciones del contenedor de acuerdo con el tipo de forma predeterminada.
propagación El atributo de propagación de la transacción se introducirá en detalle en el próximo artículo.
aislamiento El nivel de aislamiento de la transacción es formular el nivel de aislamiento de la base de datos.¿Conoce el nivel de aislamiento de la base de datos? Si no lo sabes, puedes inventarlo.
se acabó el tiempo El período de tiempo de espera (segundos) de la ejecución de la transacción. Ejecutar un método. Por ejemplo, si hay un problema, no puedo esperar por usted por un día. Tal vez solo pueda esperar por usted durante 10 segundos y 10 segundos como máximo. Si la ejecución no se completa, aparecerá una excepción de tiempo de espera.
solo lectura Si se trata de una transacción de solo lectura, por ejemplo, solo hay una operación de consulta en un método determinado, podemos especificar que la transacción sea de solo lectura. Si se establece este parámetro, la base de datos puede optimizar el rendimiento para mejorar la velocidad de la consulta.
retrocederPara Defina cero (0) o más clases de excepción. Estas clases de excepción deben ser subclases de Throwable. Cuando los métodos lanzan estas excepciones y sus excepciones de subclase, Spring revertirá la transacción. En el caso de RuntimeException o Error, la transacción se revertirá
revertir para el nombre de la clase Igual que rollbackFor, pero este lugar usa el nombre de clase
noRevertirPara Defina cero (0) o más clases de excepción. Estas clases de excepción deben ser subclases de Throwable. Cuando el método lanza estas excepciones, la transacción no se revertirá.
noRollbackForClassName Igual que noRollbackFor, excepto que aquí se usa el nombre de la clase

4. Realizar operaciones comerciales de db

Realice operaciones comerciales en clases de anotación @Transaction o métodos de destino, y Spring administrará automáticamente estos métodos para las transacciones.

Por ejemplo, la siguiente operación insertBatch elimina los datos primero y luego los inserta en lotes. La anotación @Transactional se agrega al método. En este momento, este método será controlado automáticamente por la transacción Spring y tendrá éxito o fallará.

@Component
public class UserService {
    
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //先清空表中数据,然后批量插入数据,要么都成功要么都失败
    @Transactional
    public void insertBatch(String... names) {
    
    
        jdbcTemplate.update("truncate table t_user");
        for (String name : names) {
    
    
            jdbcTemplate.update("INSERT INTO t_user(name) VALUES (?)", name);
        }
    }
}

5. Inicie el contenedor de primavera y use frijoles para realizar operaciones comerciales

@Test
public void test1() {
    
    
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(MainConfig4.class);
    context.refresh();

    UserService userService = context.getBean(UserService.class);
    userService.insertBatch("java高并发系列", "mysql系列", "maven系列", "mybatis系列");
}

Caso 1

preparar base de datos

DROP DATABASE IF EXISTS javacode2018;
CREATE DATABASE if NOT EXISTS javacode2018;

USE javacode2018;
DROP TABLE IF EXISTS t_user;
CREATE TABLE t_user(
  id int PRIMARY KEY AUTO_INCREMENT,
  name varchar(256) NOT NULL DEFAULT '' COMMENT '姓名'
);

clase de configuración de resorte

package com.javacode2018.tx.demo4;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;

@EnableTransactionManagement //@1
@Configuration
@ComponentScan
public class MainConfig4 {
    
    
    //定义一个数据源
    @Bean
    public DataSource dataSource() {
    
    
        org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8");
        dataSource.setUsername("root");
        dataSource.setPassword("root123");
        dataSource.setInitialSize(5);
        return dataSource;
    }

    //定义一个JdbcTemplate,用来执行db操作
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    
    
        return new JdbcTemplate(dataSource);
    }

    //定义我一个事物管理器
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
    
     //@2
        return new DataSourceTransactionManager(dataSource);
    }
}

@1 : use la anotación @EnableTransactionManagement para habilitar la administración de transacciones de primavera

@2 : Definir administrador de transacciones

ven a clase ejecutiva

package com.javacode2018.tx.demo4;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Component
public class UserService {
    
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //先清空表中数据,然后批量插入数据,要么都成功要么都失败
    @Transactional //@1
    public int insertBatch(String... names) {
    
    
        int result = 0;
        jdbcTemplate.update("truncate table t_user");
        for (String name : names) {
    
    
            result += jdbcTemplate.update("INSERT INTO t_user(name) VALUES (?)", name);
        }
        return result;
    }

    //获取所有用户信息
    public List<Map<String, Object>> userList() {
    
    
        return jdbcTemplate.queryForList("SELECT * FROM t_user");
    }
}

@1 : la anotación @Transactional se agrega al método insertBatch, lo que permite que Spring agregue automáticamente transacciones a este método

clase de prueba

package com.javacode2018.tx.demo4;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Demo4Test {
    
    
    @Test
    public void test1() {
    
    
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(MainConfig4.class);
        context.refresh();

        UserService userService = context.getBean(UserService.class);
        //先执行插入操作
        int count = userService.insertBatch(
                "java高并发系列",
                "mysql系列",
                "maven系列",
                "mybatis系列");
        System.out.println("插入成功(条):" + count);
        //然后查询一下
        System.out.println(userService.userList());
    }
}

ejecutar salida

插入成功(条):4
[{
    
    id=1, name=java高并发系列}, {
    
    id=2, name=mysql系列}, {
    
    id=3, name=maven系列}, {
    
    id=4, name=mybatis系列}]

Algunos amigos pueden preguntar, ¿cómo saber si el método llamado usa transacciones? Echemos un vistazo a continuación.

Cómo determinar si el método utiliza transacciones de primavera

Método 1: depuración de puntos de interrupción

La transacción de resorte es procesada por el interceptor TransactionInterceptor y, finalmente, se llamará al siguiente método, y el proceso detallado se puede ver al establecer un punto de interrupción.

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-Z9sde61c-1684550694442) (%E6%96%B0%E5%BB%BA %E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113623217-1389119179.png)]

Método 2: mira el registro

El proceso de transacciones de procesamiento de primavera tiene una salida de registro detallada. Cuando el registro está encendido, la consola puede ver el proceso detallado de la transacción.

Agregar configuración experta

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

src\main\resources nuevo logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d{MM-dd HH:mm:ss.SSS}][%thread{20}:${PID:- }][%X{trace_id}][%level][%logger{56}:%line:%method\(\)]:%msg%n##########**********##########%n</pattern>
        </encoder>
    </appender>

    <logger name="org.springframework" level="debug">
        <appender-ref ref="STDOUT" />
    </logger>

</configuration>

Ejecutemos el Caso 1 de nuevo

[09-10 11:20:38.830][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:370:getTransaction()]:Creating new transaction with name [com.javacode2018.tx.demo4.UserService.insertBatch]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
##########**********##########
[09-10 11:20:39.120][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:265:doBegin()]:Acquired Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65fe9e33]]] for JDBC transaction
##########**********##########
[09-10 11:20:39.125][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:283:doBegin()]:Switching JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65fe9e33]]] to manual commit
##########**********##########
[09-10 11:20:39.139][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:502:update()]:Executing SQL update [truncate table t_user]
##########**********##########
[09-10 11:20:39.169][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:860:update()]:Executing prepared SQL update
##########**********##########
[09-10 11:20:39.169][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:609:execute()]:Executing prepared SQL statement [INSERT INTO t_user(name) VALUES (?)]
##########**********##########
[09-10 11:20:39.234][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:860:update()]:Executing prepared SQL update
##########**********##########
[09-10 11:20:39.235][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:609:execute()]:Executing prepared SQL statement [INSERT INTO t_user(name) VALUES (?)]
##########**********##########
[09-10 11:20:39.236][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:860:update()]:Executing prepared SQL update
##########**********##########
[09-10 11:20:39.237][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:609:execute()]:Executing prepared SQL statement [INSERT INTO t_user(name) VALUES (?)]
##########**********##########
[09-10 11:20:39.238][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:860:update()]:Executing prepared SQL update
##########**********##########
[09-10 11:20:39.239][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:609:execute()]:Executing prepared SQL statement [INSERT INTO t_user(name) VALUES (?)]
##########**********##########
[09-10 11:20:39.241][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:741:processCommit()]:Initiating transaction commit
##########**********##########
[09-10 11:20:39.241][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:328:doCommit()]:Committing JDBC transaction on Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65fe9e33]]]
##########**********##########
[09-10 11:20:39.244][main: ][][DEBUG][o.s.jdbc.datasource.DataSourceTransactionManager:387:doCleanupAfterCompletion()]:Releasing JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65fe9e33]]] after transaction
##########**********##########
插入成功(条):4
[09-10 11:20:39.246][main: ][][DEBUG][org.springframework.jdbc.core.JdbcTemplate:427:query()]:Executing SQL query [SELECT * FROM t_user]
##########**********##########
[09-10 11:20:39.247][main: ][][DEBUG][org.springframework.jdbc.datasource.DataSourceUtils:115:doGetConnection()]:Fetching JDBC Connection from DataSource
##########**********##########
[{id=1, name=java高并发系列}, {id=2, name=mysql系列}, {id=3, name=maven系列}, {id=4, name=mybatis系列}]

Entendamos el registro

El método insertBatch tiene la anotación @Transaction, por lo que será interceptado por el interceptor.La siguiente es una transacción creada antes de llamar al método insertBatch.

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente (img-rdB0lIZX-1684550694443) (%E6%96%B0%E5%BB%BA% E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113718442-1842075940.png)]

Los parámetros de la anotación @Transaction en el método insertBatch son todos valores predeterminados. La anotación @Transaction se puede usar para value或者transactionManagerespecificar el administrador de transacciones, pero no se especifica. En este momento, Spring encontrará uno predeterminado en el contenedor de acuerdo con el tipo de administrador de transacciones Sucede que estamos en el contenedor de primavera Uno está definido en , por lo que se usa directamente. Usamos el administrador de transacciones para new DataSourceTransactionManager(dataSource)obtener una conexión de base de datos de la fuente de datos del administrador de un articulo

[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-rZ3WZCnB-1684550694443)(%E6%96%B0%E5%BB%BA %E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113729840-868259205.png)]

La siguiente es la entrada en el método insertBatch.Algunas operaciones de db se realizan a través de jdbctemplate.Jdbctemplate obtendrá la conexión de la transacción de primavera a través de la fuente de datos al subproceso local anterior, y luego realizará la operación de db.

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-dd7nXKAG-1684550694444)(%E6%96%B0%E5%BB%BA %E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113738775-208538673.png)]

Finalmente, después de que se ejecuta el método insertBatch, no hay excepción, Spring comienza a enviar la transacción a través de la conexión de la base de datos.

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-eUgdvJFj-1684550694444)(%E6%96%B0%E5%BB%BA %E6%96%87% E6%9C%AC%E6%96%87%E6%A1%A3/1369022-20211106113749897-572088668.png)]

Resumir

Este artículo explica los pasos para usar transacciones programáticas en primavera.

Se trata principalmente de 2 anotaciones:

@EnableTransactionManagement: habilitar la función de gestión de transacciones de primavera

@Transaction: agregarlo a clases, métodos e interfaces que requieren Spring para administrar transacciones solo será válido para métodos públicos.

Vamos a digerirlo nuevamente, si tiene alguna pregunta, deje un mensaje para intercambiar.

El siguiente artículo presentará en detalle las propiedades de propagación de las transacciones, así que permanezca atento.

Código fuente del caso

git地址:
https://gitee.com/javacode2018/spring-series

本文案例对应源码:spring-series\lesson-002-tx\src\main\java\com\javacode2018\tx\demo4

Transeúnte A Todos los códigos de casos de Java se pondrán en esto en el futuro, todos lo miren, pueden seguir prestando atención a la dinámica.

Después de eso, no hay excepción, Spring comienza a confirmar la transacción a través de la conexión de la base de datos.

[Transferencia de imagen de enlace externo...(img-eUgdvJFj-1684550694444)]

Resumir

Este artículo explica los pasos para usar transacciones programáticas en primavera.

Se trata principalmente de 2 anotaciones:

@EnableTransactionManagement: habilitar la función de gestión de transacciones de primavera

@Transaction: agregarlo a clases, métodos e interfaces que requieren Spring para administrar transacciones solo será válido para métodos públicos.

Vamos a digerirlo nuevamente, si tiene alguna pregunta, deje un mensaje para intercambiar.

El siguiente artículo presentará en detalle las propiedades de propagación de las transacciones, así que permanezca atento.

Código fuente del caso

git地址:
https://gitee.com/javacode2018/spring-series

本文案例对应源码:spring-series\lesson-002-tx\src\main\java\com\javacode2018\tx\demo4

Transeúnte A Todos los códigos de casos de Java se pondrán en esto en el futuro, todos lo miren, pueden seguir prestando atención a la dinámica.

Fuente: https://mp.weixin.qq.com/s?__biz=MzA5MTkxMDQ4MQ==&mid=2648936892&idx=2&sn=473a156dc141a2efc0580f93567f0630&scene=21#wechat_redirect

Supongo que te gusta

Origin blog.csdn.net/china_coding/article/details/130778919
Recomendado
Clasificación