【23】 Explicación detallada del negocio de primavera integrado de Springboot y combate real

        He estado en la etapa extremadamente superficial de la teoría de la entrevista para el contenido de los asuntos de primavera . De hecho, no lo he estudiado ni resumido cuidadosamente. Esta vez dediqué algún tiempo a estudiar los asuntos de primavera y resumí mis notas de estudio aquí. Empecemos con todo. En primer lugar, haré mi propia comprensión e interpretación desde el concepto de transacción de primavera hasta el uso del código.

        Comenzaremos aprendiendo paso a paso desde los siguientes puntos:

             1. ¿Qué es una transacción de primavera?

             2. ¿Por qué el proyecto Springboot recién creado a veces viene con procesamiento de transacciones y otras sin procesamiento de transacciones?

             3. Hay varias formas de utilizar y utilizar las transacciones de Spring.

             4. El ejercicio de operación de múltiples atributos de la transacción de primavera .

La demostración de este capítulo se modifica         utilizando la demostración anterior de swagger de integración de springboot y el código se cargará en git.

Navegación del grupo de intercambio Qq ——> 231378628

 La columna general del capítulo Springboot: 


[1] springboot integra swagger (súper detallado

[2] springboot integra swagger (personalizado) (súper detallado)

[3] token de integración springboot (súper detallado)

[4] springboot integra mybatis-plus (súper detallado) (activado)

[5] springboot integra mybatis-plus (súper detallado) (abajo)

[6] springboot integra manejo de excepciones global personalizado

[7] springboot integra redis (súper detallado)

[8] springboot integra AOP para realizar operaciones de registro (súper detallado)

[Nueve] tareas de sincronización integradas de Springboot (súper detalladas)

[10] springboot integra redis para realizar el servicio de inicio, es decir, guardar los datos del punto de acceso en global y redis (súper detallado)

[Eleven] Springboot integra Quartz para optimizar las tareas de sincronización (súper detallado)

[Doce] Springboot integra el grupo de subprocesos para resolver la alta concurrencia (súper detallado, para que sigas comprendiendo)

[Trece] springboot integra llamadas asincrónicas y obtiene valores de retorno (súper detallado)

[14] springboot integra WebService (súper detallado)

[Quince] Springboot integra WebService (sobre pasar parámetros) (súper detallado)

[16] springboot integra WebSocket (súper detallado)

[Seventeen] Springboot integra WebSocket para realizar una sala de chat (súper detallado)

[Dieciocho] Springboot implementa un manejo de excepciones global personalizado

[Diecinueve] Springboot integra el combate real de ElasticSearch (diez mil caracteres)

[Veinte] combate de filtro de integración springboot

[21] springboot integra interceptores en combate real y compara filtros

[22] actividad de integración de springboot7 (1) demostración práctica

【23】 Explicación detallada del negocio de primavera integrado de Springboot y combate real

[24] Springboot utiliza EasyExcel y un grupo de subprocesos para realizar la importación de datos de Excel mediante subprocesos múltiples

[25] springboot integra filtros jedis y redisson Bloom para manejar la penetración de caché

[26] springboot implementa el procesamiento de transacciones multiproceso_springboot transacción multiproceso

[27] springboot realiza la función de guardar la información de inicio de sesión actual como la sesión a través del analizador de parámetros threadLocal +


a9c53926625446808a2e15b6c7d63e87.png

Tabla de contenido

1. ¿Qué es una transacción de primavera?

2. ¿Por qué el proyecto Springboot recién creado a veces viene con procesamiento de transacciones y otras sin procesamiento de transacciones?

3. Cómo utilizar las transacciones de primavera y cómo utilizarlas

Cuarto, la operación práctica de múltiples atributos de las transacciones de primavera.

1. Si la transacción solo tiene permiso de lectura (solo lectura)

2. La transacción se revierte después de que se produce la excepción especificada (reversión para)

3. No revertir después de que ocurra la excepción especificada en la transacción (no-rollback-for)

4. Nivel de aislamiento de transacciones (aislamiento)

5. Propagación de transacciones (propagación)

6. Tiempo de espera de la transacción (tiempo de espera)


1. ¿Qué es una transacción de primavera?

        Las transacciones de Spring son similares a las transacciones de MySQL y también son las características y funciones de las transacciones de MySQL.

Cuatro características de las transacciones:

nombre describir
consistencia La integridad de los datos debe permanecer constante antes y después de la ejecución de la transacción.
atomicidad Una transacción es una unidad indivisible y el contenido que contiene se ejecuta o no se ejecuta.
aislamiento Cuando varios usuarios acceden a la base de datos al mismo tiempo, las transacciones de varios usuarios no se afectan entre sí y los datos de varias transacciones simultáneas deben aislarse entre sí.
Persistencia Las modificaciones a la base de datos por transacciones comprometidas deben almacenarse permanentemente en la base de datos.

Nivel de aislamiento de transacciones :

        Las tablas se describen en la segunda sección a continuación y no se repetirán aquí.

Mecanismo de propagación de transacciones:

        La tabla en la segunda sección a continuación también se describe, por lo que no la repetiré aquí, si quieres verla, baja las escaleras.

Resumir:

        Los asuntos de primavera son probablemente estos puntos. El propósito más común de usarlo son sus cuatro características principales. Creo que la más importante es la atomicidad, mantener las operaciones de la base de datos en el método, ya sea que todas tengan éxito o todas fallen.

        /El siguiente es un estudio sobre por qué a veces siento que el procesamiento de transacciones parece haber venido con el proyecto y, a veces, siento que no hay procesamiento de transacciones./ .


2. ¿Por qué el proyecto Springboot recién creado a veces viene con procesamiento de transacciones y otras sin procesamiento de transacciones?

        Para resolver este problema, debe ir al proyecto para averiguar si dicha clase DataSourceTransactionManager está registrada en el contenedor Spring. Si existe, puede usar la transacción. Si no existe, debe importar el jar dependiente. paquete con esta clase, similar a mybatis y spring-jdbc Depende de esta clase a continuación.

1fee1d8d7e5d4a499315caecf4b3e01c.png

        Después de encontrar esta clase, significa que su proyecto admite el procesamiento de transacciones, pero el problema es si está abierta o la transacción no es válida. A continuación se presentan dos formas de abrir la transacción. Este artículo se centra en explicar el formato xml + aop (para facilitar el procesamiento global).


3. Cómo utilizar las transacciones de primavera y cómo utilizarlas

        Como se mencionó anteriormente, cuando la clase DataSourceTransactionManager existe en el proyecto, se pueden usar transacciones. Hay dos formas de iniciar transacciones, de la siguiente manera:

método abierto Operación concreta
método de anotación

1. Agregue la anotación @EnableTransactionManagement a la clase de inicio para habilitar la función de procesamiento de transacciones.

2. Anote @Transactional en el método que requiere procesamiento de transacciones para realizar el procesamiento de transacciones.

forma xml

1. Cree un nuevo archivo xml, cree nuevas etiquetas bean, tx, aop y configure los lugares que necesitan procesamiento de transacciones.

2. Importe el recurso a través de la anotación @ImportResource en la clase de inicio @ImportResource("classpath:transaction.xml")

Utilice uno de los         dos métodos anteriores .

A continuación se muestran los dos métodos:

1: método de anotación (este capítulo no se centra en la explicación)

Cuando no se abre una transacción:

d8c1c3185add44a88503fb422f985edc.png

5be1f4eb5fdf4e1f95aec461c61900bf.png

Como puede ver en el código anterior, después de ejecutar la declaración de guardado de mybatis-plus, se informará un error y la excepción no se maneja manualmente. En este caso, ¿el guardado se realizará correctamente? La respuesta es sí, debido a que no hay procesamiento de transacciones, la prueba es la siguiente:

Hoja de datos antes de la prueba:

0d805942446f46039a4025192f074465.pngLlame a la interfaz de prueba:

42391efdc7194deb910b14315a9d96a4.png

Tabla de datos después de la prueba:

9f0fcb89f3cd4c049ffcb6b8c4f82dd7.png

resultado:

Aunque se informó un error, los datos aún se guardaron y no se realizó ningún procesamiento de transacción automáticamente

Al iniciar una transacción:

cae9fd0d27bd4957a46614a4ae0f8db1.png

0e2d7d3ef8ea43d6bc901d647135fccf.png

El procesamiento de transacciones se habilita mediante anotaciones y se está probando lo siguiente.

Hoja de datos antes de la prueba:

612ad8ef9f8b42a29c034dc383c1e923.png

Llame a la interfaz de prueba:

22e7af892b774de791e07ec441ae6804.png

La interfaz aún informa un error donde el denominador del cálculo del código es 0.

Hoja de datos después de la prueba:

ccc6246be3aa488180173aef8bd78918.png

Los datos en la tabla de datos no se agregan, lo que significa que los datos se revierten después de que se informa un error , lo que significa que se ha realizado el procesamiento de la transacción y el procesamiento de la transacción se ha abierto con éxito. Pero este método tiene un gran problema : es necesario agregar anotaciones @Transactional a todos los métodos que requieren procesamiento de transacciones . Se puede realizar mediante xml + aop. El objeto de aprendizaje clave de este capítulo es realizar el procesamiento de transacciones de Spring mediante xml.

2: modo xml

Cuando no se abre una transacción:

Elimine las dos anotaciones agregadas durante la prueba anterior y luego pruebe el procesamiento de transacciones de la interfaz. Lo anterior ha sido probado y no se escribirá aquí.

Al iniciar una transacción:

Método de apertura: *******************

Primero cree el archivo transaction.xml, de la siguiente manera:

<?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:aop="http://www.springframework.org/schema/aop"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.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">

	<!--  定义事务管理对象	-->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" ></property>
	</bean>

	<!--  配置事务处理	-->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="*" read-only="true" timeout="7200" />
			<tx:method name="get*" rollback-for="Exception" read-only="true" ></tx:method>
			<tx:method name="add*" ></tx:method>
			<tx:method name="delete*" rollback-for="Exception" read-only="true" ></tx:method>
			<tx:method name="update*" rollback-for="Exception" read-only="true" ></tx:method>
		</tx:attributes>
	</tx:advice>

	<!--  配置aop的切点和切点的处理	-->
	<aop:config>
		<aop:pointcut id="allManagerMethod" expression="execution (* com.swagger.demo.service.UserService.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="0"/>
	</aop:config>

</beans>

El código se interpreta de la siguiente manera: 

b0ed23cd958047d1b530b2b661d0ae55.png​1 : Aquí está la definición del objeto de gestión de transacciones, que es la clase mencionada anteriormente. La captura de pantalla aquí es popular porque el archivo de configuración no se ha importado a la clase de inicio del proyecto Springboot.

a9950e22948e4d2e8b45e961ed779c16.png

2: Defina el punto de corte a través de aop y corte al lugar donde se debe procesar la transacción. El método de coincidencia interno es la regla de coincidencia del punto de corte de aop. Baidu, no hay muchas cosas, así que no expandiré aquí. 

571eab00d8f6459185e0430609b90079.png

3: Cree la etiqueta tx, asocie el objeto aop con el objeto de gestión de transacciones y configure el lugar donde se requiere el procesamiento de transacciones. Las propiedades de la etiqueta tx se explican a continuación.

Nombre del Atributo describir

nombre

El nombre del método de procesamiento de transacciones se puede hacer coincidir de forma aproximada con el nombre del método mediante *, y el método de procesamiento es la posición donde corta el punto aop. No hay ningún valor predeterminado .

solo lectura

Si la transacción solo tiene acceso de solo lectura a la base de datos, verdadero, falso, el valor predeterminado es falso .

revertir-para

Revertir después de que ocurra la excepción especificada, separada por comas, el valor predeterminado es runtimeException

aislamiento

Nivel de aislamiento de transacciones.

1: predeterminado: la base de datos determina automáticamente qué nivel de aislamiento se debe utilizar. El valor predeterminado es predeterminado .

2: read_uncommitted: se pueden leer datos no confirmados. Pueden producirse lecturas sucias, lecturas únicas y lecturas fantasma. Máxima eficiencia.
3: read_committed: solo puede leer datos confirmados por otras transacciones. Se pueden evitar lecturas sucias y pueden producirse lecturas no repetibles y lecturas fantasma.

4: lectura_repetible: los datos leídos están bloqueados para evitar que otras transacciones modifiquen estos datos. Puede evitar lecturas sucias, lecturas no repetibles y posibles lecturas fantasma.
5: serializable: operación en cola, bloquea toda la tabla. Cuando una transacción opera datos, otra transacción debe esperar a que se complete la operación de transacción antes de operar la tabla.

sin reversión para

Cuando ocurre la excepción especificada, no se revertirá. Los múltiples están separados por comas y no hay un valor predeterminado .

propagación

Propagación de transacciones.

1: OBLIGATORIO: Admitir la transacción actual, si no hay una transacción actual, crear una nueva transacción. Esta es la opción más común. (por defecto OBLIGATORIO)

2: SOPORTES: Admite la transacción actual, si no hay una transacción actual, se ejecutará de manera no transaccional.

3: OBLIGATORIO: Admite la transacción actual; si no hay una transacción actual, se generará una excepción.

4: REQUIRES_NEW: crea una nueva transacción, si hay una transacción actual, suspende la transacción actual.

5: NOT_SUPPORTED: Ejecute la operación de manera no transaccional, si hay una transacción actual, suspenda la transacción actual.

6: NUNCA: Ejecutar de manera no transaccional, si hay una transacción actual, se lanza una excepción.

7:NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

timeout

事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务,没有默认的超时时间。

ps:创建好xml文件后,其次记得要引入aop的jar包,不然启动报错,因为xml文件使用了aop的标签。

c8ea062567f74d5692e2cc27d41e7fbe.png

最后,启动类导入该文件,@ImportResource("classpath:transaction.xml")

这个东西注意了,必须加上,否则事务配置的xml文件不会生效,一定记得加哦!!!

2d376460f9834c7884074c6321e5f4ac.png

创建好xml文件并导入后,我们继续测试add方法,并采用所有的默认spring事务配置进行测试(后面小节进行其他属性的一一测试)。  

32d142a936bd43bba74aa7f4b53ad877.png

测试前数据表:

4685e2c6c66c4cbeb5ae57dd76fae7e6.png

调用接口:

d2560bff7a2642608beea027f797987f.png

测试后数据表:

a592ac64c4bf4532b1513035b93d270e.png

数据表没有新增数据,说明采用标签的默认的事务处理是生效了的。后面小节针对上面表格的6个属性值(read-only,rollback-for,isolation,no-rollback-for,propagation,timeout)进行学习。


四、spring事务的多个属性的实际操作演练

1、事务是否只有可读权限(read-only)

        针对这个属性的学习还是拿上面的add方法进行测试。

false时:

cecde198a43e469db161aee85f58f0b9.png

c85ee17b9cf44d52bf909ca53d449779.png

默认是false,所以当不写时就是false,测试上面add方法是否会新增成功呢?答案是:肯定会

2f63754045d14be5a05f7dfca2bd2241.png

7c1c87308361425d9a2206669f6d490b.png

true时:

82dc7ae5590c4390816a7d47437ae9db.png

6406353d73384eabb69e8c969bba4860.png

        上面这种情况时呢,会发生什么?

46d507489eb545118c4e381987016b29.png

17234fa455714fac9d22664bfb86425c.png

46a9e28e2143494896e6120801e270ec.png

        可以发现接口报了sql异常了,连接只可以读,数据库数据也没有新增,确实进行了事务处理

        接下来再试试另一个参数rollback-for的学习,指定异常回滚


2、事务发生指定的异常后回滚(rollback-for

        由于Spring事务的回滚会自动回滚发生的runtimeException异常,所以本小结的学习自定义一个自己的异常类型——MyException

6520f0d5b8314c94a6556d4dc37f9a37.png

        然后改造add方法。如下:

3615ea56295247e39b6648a140a93438.png

        手动捕获这个runtimeException异常,然后由我们自己手动抛一个自定义的异常出去,再不修改 rollback-for属性的情况下,调用接口,事务会回滚吗?答案是不会,因为我自定义的异常继承自Exception,而不是运行时异常,测试看看,调用接口前数据库表是这样的:

c3b121704d784130be616f017549289b.png

调用接口后:

213f457ede454e628be762393075eef3.png

b77785938e2245c895ec40a7fce614e1.png

9eafa2d9e83746e398c80b62ac77c43a.png

        虽然报错了,但是数据库数据仍然新增成功了,并没有回滚,没有事务处理

        下面试试rollback-for属性的作用。

ed3a52d8f50e418584d24985bc520b89.png

        再进行测试。

测试前数据表:

efe93a32d78440bcbddc59b45b60f236.png

调用接口后:

c4c86a55e145416bb9404ab39a631322.png​ b27ef227696345878e7bf5b69cb3c089.png

        数据显然没有新增成功,所以事务回滚了,进行了事务处理,rollback-for的作用体现出来了,若需要让事务处理多个自定义异常的话,用逗号隔开即可,如:<tx:method name="add*" rollback-for="MyException,MyException2,MyException3" ></tx:method>。

补充:关于异常回滚这块,需要注意一个东西:try-catch手动捕获异常,即使是runtimeException类型的异常,若手动捕获了异常并没有再抛出runtimeException异常(要把异常抛出去,抛到方法外让别人能发现,不能自己抓起来),就不会进行事务处理了就是所谓的事务失效

        意思就是如下情况:

58b977b9b2cc461eab32dbb6537d7003.png

手动捕获,但是抛出了运行时异常,能回滚

c60e508ea38549efa6393644941ca56f.png

手动捕获,但是未做其他处理,不能回滚

c2b62eb0d25445638942275391cecfe9.png

直接抛出运行时异常类ArithmeticException,继承至运行时异常类,能回滚

        言归正传,下面学习no-rollback-for属性,设置指定异常不回滚


3、事务发生指定的异常后不回滚(no-rollback-for

        上面有说到运行时异常都会进行事务处理,demo中的ArithmeticException异常就是runtimeException,若现在我需要设置即使发生这个异常也不回滚,怎么做呢?下面就可以通过这个属性实现。

27ce5b0e9c7640a9b34976d8f5730d58.png

        上面已经测试过发生这个异常会回滚,所有这里直接测试将这个属性设置到no-rollback-for属性,测试是不是不会回滚?

fa28804eb26442e88189170e6be35ad8.png

30f74b1fc11144b5b8ae8f867df3cf0e.png

测试前数据库表:

81c7cda2d6b2452b83146d20250f55fb.png调用接口:

804e0b0823ed4349a33faaf10154da00.png

c660e833db284d7bac8b46aa8ea18503.png

00edcacf0ee6455ab6a4ecf38f07dde6.png

        虽然报错了,但是仍然插入了数据,说明的确在设置no-rollback-for属性值为ArithmeticException时,Spring事务不回滚了,前面的提出的假设需求就回答了,这就是no-rollback-for属性的作用。同样的,若需要处理多个异常不进行事务处理,就用逗号隔开即可。


4、事务隔离级别(isolation

        事务隔离级别一直都是懵懵懂懂的概念,这次浅学一下。

        isolation属性就是设置事务隔离级别的,默认是default(由数据库自动判断应使用什么隔离级别)。

        这一小节就测试一下read_uncommitted(可以读取未提交的数据。可能出现脏读、不重复读、幻读。效率最高)。

        首先先查看下自己的mysql是使用的什么隔离级别

mysql版本 查看隔离级别方式
8.0以上

select @@transaction_isolation 

8.0以下

select @@tx_isolation

f332772ff4d1421e95d437dc2d29029a.png

        这是我的(可重复度,即mysql默认的隔离级别) 。

        下面开始通过两个接口来测试事务隔离级别读未提交(read_uncommitted)。

        现在模拟一种情况张三在新增一个用户"马冬梅",但是事务还没有执行完,还没有提交到数据库,这个时候李四上去查询用户,如果是default情况下,李四是肯定查询不到"马冬梅"的,为default时,我已经测试过了,查询不到,但是我现在抽风了,我就是要查询到这个"马冬梅",怎么办?就可以设置事务隔离级别为读未提交,下面开始整这个demo。

        1、还原add方法,并新增一个get方法用于查询所有用户。 

e8891576a4774170aa7d513c71be6e12.png

       2、改造xml文件,设置这两个方法的事务隔离级别。

33ec047640d144f9b591831c8b28df5d.png

        3、运行这个项目,跑两个端口,一个给张三用于新增,一个给李四用于查询。

0586d1f9d9a6426d95cbc32d7af1eb7d.png

        先看看现在表的情况。

427d3eec11404742a34c8b2fee2fe3bb.png

        有这样5条数据。

        张三现在用8085端口新增马冬梅(在add方法加个断点,防止数据立刻提交),李四用8086查询

b2b4b73933ff4810894be41dfac28e3b.png

        张三新增马冬梅,断点不放开。

9719404ef1b64d348c798ac80ad8ee81.png

13da00933f7a4b16b84d555ed9250939.png​        可以看到数据库表数据未新增,因为事务还没有提交嘛。现在让李四到8086端口查询。

0a403460794f46329336c8867752cfd6.png

        可以看到,李四查询出了张三还未提交事务到数据库的数据"马冬梅"。

        后面的其他隔离级别这里就不写了,太多了。 


5、事务传播性(propagation

        除了事务隔离级别,还有个事务传播机制也经常被面试官问到,趁现在也大概学习一下。

        本小结通过设置REQUIRED(支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是最简单的处理)进行学习。默认的传播机制是也是REQUIRED。通过学习,我认为事务传播性基本上就是发生在多个方法上,比如A方法有事务,A方法内调用B方法,而B方法也有事务,或者A方法没有事务时,事务它到底如何处理,这就是事务传播机制。

        我先用语言描述一下我对于默认的REQUIRED的了解。

        假设如果有一个A方法需要新增用户的基本信息,而B方法需要新增他的父亲和母亲的基本信息,则在A方法新增完自己的信息后调用B方法。若两个方法都存在事务时,则B方法的事务就不会创建,而是和A方法公用一个事务,意思就是出异常了就一起回滚;而若方法不存在事务,B方法存在事务,就会新建一个B方法自己的事务,A方法出异常也不会回滚,而B方法会回滚。

        下面通过代码实现。

        新建一个service和实现类存放新增父母信息的方法(原因:放在同一个类下会发生事务失效的问题,我试了很久,你也可以试一下,要放在不同类下),如下:

1659ac9725de471081614acd0101cccf.png

1、新增addFather方法

8b5fb800e0214a558c96c551988d72e0.png​2、改造原来的add方法

34c9080fdc9b4452a0e59eeb00a09635.png​3、新增addFather方法的事务处理

f8aa1cc674d044d8b46d31704f4baf8f.png

测试前数据表数据:

8989cd2ac57d4d829c6626c5a84b62a7.png调用接口测试:

10eab4eaa3d349e1bb7d3845839340ba.png

4d572e6183cb42fcbaa085dcacebbc95.png

02f162069ef74a29bbbb268781e2dce3.png​        发现数据库没有新增数据,两个方法的事务都回滚了,说明第二个事务在发现当前存在事务时,直接加入了第一个事务,只存在同一个事务。

        La siguiente prueba es que si solo B tiene una transacción y A no tiene una transacción, B creará una nueva transacción y la predicción del efecto será que Ma Dongmei agregará con éxito una nueva transacción, pero sus padres no agregarán con éxito una. nueva transacción.

La operación de prueba es la siguiente:

1. Cierre la transacción del método add y abra solo la transacción del método addFather

0c0a11c593b44a7a83a0eebd682fe099.png

Hoja de datos antes de la prueba:

8989cd2ac57d4d829c6626c5a84b62a7.png

Interfaz de llamada:

1b2d1afd5be047619c4d2abb852b86b7.png

0eb17dfebf464ec3bac50d33b6bfd326.png

9b40082c42094c53bb7620b35f4900fc.png

        Resultado: se produjo una excepción en tiempo de ejecución y la transacción del método B se revirtió , pero la transacción del método A no se revirtió , lo que indica que el método B creó una nueva transacción propia cuando no existe ninguna transacción actualmente.


6. Tiempo de espera de la transacción ( tiempo de espera )

        Para estudiar el tiempo de espera de las transacciones, continúe aprendiendo a través de la demostración del método agregar.

Nota: El tiempo de espera aquí es el tiempo de espera de la conexión de la base de datos, no el tiempo de espera de todo el método. Si está interesado, puede probar la suspensión del subproceso en el método. Puede ver que la transacción no se revertirá. Lo he intentado. eso, jaja.

        Modifique el método de adición, debido a que cada método de inserción es demasiado corto, déle directamente un bucle 10,000 veces.

antes de probar:

aded01e6a71248be825c5e855b06842d.png

4b420dd4192d4fb6aa09a1693eb074e9.png

95bb80b057874b049abfcc5ce77c4725.png

Después de llamar a la interfaz:

66be7aa4c5f1411f80a17d311f6a0ab2.png

587139b6c4374206a2a8204e19be62a1.png

a279c30a2ec048d28404a134fd830ac9.png

        Se activa con éxito una transacción de tiempo de espera . Cuando estaba estudiando, no pude probar el efecto de este período de tiempo de espera y siempre sentí que era inútil. Simplemente le di un tiempo de espera de 1 milisegundo, luego retrocedí y finalmente funcionó. Recuerde: solo la operación jdbc que requiere mucho tiempo después de la conexión de la base de datos se cuenta como período de tiempo de espera, y el período de tiempo de espera del código comercial en el método no se cuenta (recuerde este pequeño pozo).

Supongo que te gusta

Origin blog.csdn.net/weixin_56995925/article/details/125577851
Recomendado
Clasificación