Serie Java Entrevista Asalto (9): Transacciones en Spring

Transacciones en Spring

Qué es una transacción

Transacción: Es la unidad de trabajo más pequeña para las operaciones de la base de datos. Es una serie de operaciones que se realizan como una sola unidad lógica de trabajo. Estas operaciones se envían como un sistema como un todo, ya sea ejecutado o no ejecutado; una transacción es un conjunto de operaciones indivisibles (Unidad lógica de trabajo)

En términos simples, una serie de operaciones para lograr un propósito determinado tienen éxito juntas (confirmación de transacción) o fallan juntas (reversión de transacción)

El ejemplo más común es la transferencia de dinero:

Xiao Ming transfiere dinero a Ruhua:

开启事务-------
① 从小明的账户扣除1000元
② 给如花的账户增加1000元
事务提交-------

Cualquier paso del ejemplo anterior hará que la transacción retroceda si hay un problema.

imagen-20200503101957103

Desde llegar hasta casarse es la sumisión de los asuntos, y la mujer le pide al hombre que la persiga de nuevo. Una vez que los asuntos se revierten ~

Cuatro características del negocio

ACID es la característica básica de la transacción: fórmula (un aislamiento permanente original)

  • Atomicidad: Una transacción es una operación atómica que consta de una serie de acciones. La atomicidad de la transacción asegura que las acciones se completen o sean completamente ineficaces.
  • Coherencia: después de que se ejecuta la transacción, el estado de la base de datos es coherente con otras reglas comerciales, como el negocio de transferencias, independientemente de si la transacción se ejecuta con éxito o no, la suma de los saldos de las dos cuentas involucradas en la transferencia no debe modificarse.
  • Aislamiento: Aislamiento significa que en operaciones concurrentes, se deben aislar diferentes transacciones, de modo que cada transacción concurrente no interfiera entre sí.
  • Durabilidad: una vez que la transacción se envía con éxito, todas las operaciones de datos en la transacción deben persistir en la base de datos. Incluso si la base de datos falla inmediatamente después de que se envía la transacción, cuando se reinicia la base de datos, se debe garantizar que los datos se restauren a través de un cierto mecanismo.

Operaciones de transacciones nativas de JDBC

try {
	// 设置是否自动提交
	connection.setAutoCommit(false)
	
	// 数据库操作 insert,update,delete
	
	connection.commit()
} catch(Exception ex) {
	// 回滚
	connection.rollback()
} finally {
	connection.setAutoCommit(true)
}

Nivel de aislamiento de transacciones

Los niveles de aislamiento de transacción de base de datos son 4, de bajo a alto son: Read uncomomitted(读取未被提交的数据), Read committed(读取以被提交的数据), Repeatable read(可重复读), Serializable(完全隔离). Además, en las operaciones concurrentes de transacciones, pueden producirse lecturas sucias, lecturas no repetibles, lecturas fantasma y pérdida de transacciones.

Cuatro niveles de aislamiento

Leer sin compromiso

La lectura no confirmada, como su nombre lo indica, es que una transacción puede leer los datos de otra transacción no confirmada, lo que resultará en lecturas sucias.

Leer comprometido

这种使用的概率比较高,因为很多时候我们就以最后一次读取的为准

Read commit, como su nombre lo indica, es que una transacción no puede leer datos hasta que se confirme otra transacción, lo que provocará lecturas no repetibles.

Lectura repetible

相当于加锁,MySQL的默认级别

La lectura repetida significa que cuando se comienzan a leer los datos (se inicia la transacción), las operaciones de modificación ya no están permitidas y pueden ocurrir lecturas fantasmas.

Serializable

El nivel más alto de aislamiento de transacciones. Bajo el nivel modificado, las transacciones se ejecutan en serie, lo que puede evitar lecturas sucias, lecturas no repetibles y lecturas fantasmas. Sin embargo, este nivel de aislamiento de transacciones es ineficiente y consume el rendimiento de la base de datos, por lo que generalmente no se usa

para resumir

El nivel de aislamiento de transacciones predeterminado de la mayoría de las bases de datos es : Read Committed, como SqlServer, Oracle

El nivel de aislamiento predeterminado de MySQL es lectura repetible

Posibles problemas

Lectura sucia

读取了未提交的新事务,然后被回滚了

La transacción A lee los datos que aún no se han comprometido en la transacción B. Si la transacción B se revierte, A lee usando los datos incorrectos

imagen-20200503111507422

No repetible

读取了提交的新事物,指更新操作

La lectura no repetible significa que para ciertos datos en la base de datos, múltiples consultas dentro del alcance de una transacción pero de regreso a diferentes valores, esto se debe al intervalo de consulta, modificado y enviado por otra transacción.

imagen-20200503114507968

Una solución para resolver la lectura no repetible es ajustar el nivel de aislamiento.

Lectura fantasma

读取了提交的新事物,指增删操作

En la configuración de lectura múltiple de la transacción A, la transacción B realiza nuevas operaciones en los datos, lo que resulta en datos inconsistentes leídos por la transacción A varias veces

imagen-20200503114709457

Otra comprensión de la lectura fantasma puede ser:

幻读就是指新增了数据记录条数,第一次查询数据记录数为1000,再次查询的时候,变成了1001,这个就是幻读

La diferencia entre lectura no repetible y lectura fantasma

Mucha gente tiende a confundir la lectura no repetible y la lectura fantasma, de hecho, las dos son algo similares. Pero la lectura no repetible se centra en actualizar y eliminar, mientras que la lectura fantasma se centra en insertar

  • Lectura no repetible, solo los registros que cumplen las condiciones deben bloquearse 避免不可重复读需要锁行就行
  • La lectura fantasma debe bloquear los registros que cumplen las condiciones y su cierre. 避免幻读则需要锁表

Entonces, la mayor diferencia entre la lectura no repetible y la lectura fantasma es cómo resolver los problemas que generan a través del mecanismo de bloqueo.

Transacción perdida

Se pierde el primer tipo de transacción.

称为:回滚丢失

Para el primer tipo de pérdida de transacción, por ejemplo, A y B están ejecutando un dato al mismo tiempo, y luego se ha enviado la transacción B, y luego se revierte una transacción, de modo que la operación de la transacción B se pierde debido a la reversión de una transacción.

imagen-20200503115622743

El segundo tipo de transacción se pierde

称为:覆盖丢失

Para el segundo tipo de pérdida de transacción, también conocida como pérdida de cobertura, es que A y B ejecutan un dato juntos, y ambos obtienen un dato al mismo tiempo, luego la transacción B se envía primero, pero la transacción A se envía nuevamente, por lo tanto que cubre la transacción B

imagen-20200503121151996

Cómo Spring configura las transacciones

具体说出一些关键的xml元素

Prepare la hoja de datos:

imagen-20200503212336011

Clase de entidad:

public class User {
	private Integer id;
	private String name;
	private Integer money;
}

Dao:

Inserte la descripción de la imagen aquí

Servicio: un escenario de error por defecto

imagen-20200503221133377

Transacción programática

Transacción de configuración XML: agregue el administrador de transacciones y la configuración de la plantilla del administrador de transacciones en applicationContext.xml

imagen-20200503222130639

Administrador de transacciones de configuración del modo de anotación y plantilla de administrador de transacciones

imagen-20200503222459984

Transacción declarativa

基于AspectJ XML方式

Nota: Basado en TransactionProxyFactoryBean, el método proxy es un método más antiguo, no lo describiremos aquí.

Elimine la configuración de la plantilla de gestión de transacciones en applicationContext.xml, que es la siguiente configuración:

<!-- 事务管理的模板 -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
	<property name="transactionManager" ref="transactionManager" />
</bean>

Agregar definición de transacción y configuración de AOP

<!--基于AspectJ 申明式事务XML配置方式-->
<!-- 定义一个增强 -->
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<!-- 增强(事务)的属性的配置 -->
    <tx:attributes>
    <!-- isolation:DEFAULT ,事务的隔离级别。
    propagation:事务的传播行为.
    read-only:false,不是只读
    timeout:-1
    no-rollback-for:发生哪些异常不回滚
    rollback-for:发生哪些异常回滚事务
    -->
    <tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>
<!-- aop配置定义切面和切点的信息 -->
<aop:config>
    <!-- 定义切点:哪些类的哪些方法应用增强 -->
    <aop:pointcut
    expression="execution(* com.dk.beans.service..*.*(..))"
    id="mypointcut" />
    <!-- 定义切面: -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut" />
</aop:config>

Cambiar la clase ejecutiva a la forma original

/**
* 沒有事務的转账的业务
* @param fromName
* @param toName
* @param money
*/
public void transfer(String fromName, String toName, Integer money) {
    
    
    userDAO.out(fromName, money);// 转出钱
    int x = 10;
    if(x == 10)
    throw new RuntimeException("出错啦!");
    userDAO.in(toName, money);// 收入钱
}

Transacción declarativa basada en anotaciones:
configure @EnableTransactionManagement en la clase de configuración para habilitar la transacción. Eliminar @Bane relacionado con la transacción en la clase de anotación

Complete la configuración de la transacción a través de @Transactional por encima de la clase UserService o por encima del método:

@Service
@Transactional
public class UserService {
    
    

}

Las transacciones declarativas se pueden configurar según el método correspondiente al inicio de la transacción

<!-- 以insert开头的方法配置事务 -->
<tx:method name="insert*" isolation="DEFAULT" propagation="REQUIRED"/>

Características de propagación de transacciones de primavera

Se refiere a cómo debe proceder el método de transacción cuando otro método de transacción llama a un método de transacción. por ejemplo

public class PersonService {
    
    
    @Transactional
    public void laoda(){
    
    
        System.out.println("老大的方法");
        xiaodi();
    }
    @Transactional
    public void xiaodi(){
    
    
        System.out.println("小弟方法");
    }
}

Es decir, cuando el método del jefe llama al método del hermano menor, ¿qué se debe hacer con los asuntos del hermano menor?

Suponiendo que el método del jefe sea anormal, ¿el hermano menor necesita retroceder?

Suponiendo que el método del hermano menor es anormal, ¿es necesario revertir el método del jefe?

Hacer nada

  • PROPAGATION_NEVER: si no hay ejecución de transacción, si hay una excepción, se lanzará
  • PROPAGATION_NOT_SUPPORTED: si no hay ejecución no transaccional, si hay una suspensión directa, entonces ejecución no transaccional
    • Esto es propenso a estancarse

Dispensable

  • PROPAGATION_SUPPORTS: Úselo si lo tiene, olvídelo si no lo tiene

Debe tener aventuras

  • PROPAGATION_REQUIRES_NEW: Si hay transacciones nuevas, si hay transacciones originales, se suspenderán las originales. Es decir, las transacciones están completamente aisladas, una transacción no afecta a otras transacciones.
  • PROPAGATION_NESTED: Si no es así, cree una nueva transacción; si la hay, anida otras transacciones en la transacción actual. Transacción anidada significa que la transacción externa es anormal y la transacción interna se revierte por completo
  • PROPAGATION_REQUIRED: (configuración predeterminada) Si no es así, cree una nueva transacción; si la hay, únase a la transacción actual
  • PROPAGATION_MANDATORY: Si no es así, lanza una excepción; si es así, usa la transacción actual.

Supongo que te gusta

Origin blog.csdn.net/weixin_43314519/article/details/109767186
Recomendado
Clasificación