Gestión de transacciones TransactionTemplate y anotaciones @Transactional en Spring

1. Spring admite la gestión programática de transacciones TransactionTemplatey la gestión declarativa de transacciones @Transactionalde dos maneras

En comparación con las transacciones programáticas, la única desventaja de las transacciones declarativas es que las transacciones más detalladas solo se pueden aplicar al nivel de método y no se pueden aplicar al nivel de bloque de código como las transacciones programáticas. Pero incluso si existe tal requisito, existen muchas soluciones alternativas, por ejemplo, puede separar los bloques de código que necesitan administración de transacciones en métodos, etc. (como use AopContext.currentProxy()).

2. @TransactionalSe puede AopContext.currentProxy()resolver que en la misma clase, el método no transaccional A llama al método transaccional B, y la transacción falla

A llama al método B y la conexión del método B no es válida, pero la clase de proxy se crea agregando AopContext.currentProxy(), y la conexión se realiza antes y después de llamar a este método en el proxy clase. Para el método B proxy.B, el proceso de ejecución consiste en registrar primero el registro y luego llamar al cuerpo del método, pero la llamada en el método A proxyA solo puede mejorar A, y la llamada a B en A usa el objeto.B( ) en lugar de $proxy .B(), por lo que el corte en B no es válido.

Nota: AopContext.currentProxy() usa ThreadLocal para guardar el objeto proxy, por lo que
AopContext.currentProxy().B() puede resolverlo.

public class Demo {

    public void methodA () {
        ...
        // 获取当前代理类,保证同一个类中非事务方法调用事务方法时事务生效
        ((Demo) AopContext.currentProxy()).methodA();
        ...
    }      

    @Transactional(rollbackFor = Exception.class)
    public void methodB () {
        ...
    }      
}
  • Usar @Transactionaltransacciones declarativas
están en la misma clase transferir Si la transacción es válida
en diferentes clases El método transaccional A llama al método no transaccional B La transacción entra en vigor
en diferentes clases El método no transaccional A llama al método transaccional B La transacción entra en vigor
en la misma clase El método transaccional A llama al método no transaccional B La transacción se propaga y la transacción entra en vigor.
en la misma clase El método no transaccional A llama al método transaccional B falla de transacción

Reimpreso: https://www.jianshu.com/p/2ab568e7aaf7

3. Uso de TransactionTemplate de transacciones programáticas

public class Demo {

    @Resource
    private TransactionTemplate transactionTemplate;

    public void methodA () {
        ...
        // 指定事务传播性(可不设置,默认是`PROPAGATION_REQUIRED`)
         transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 指定事务隔离级别(可不设置,默认是`ISOLATION_DEFAULT`,同数据库隔离级别)
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
        transactionTemplate.execute(transactionStatus -> {
            methodB();
            return Boolean.TRUE;
        });
        ...
    }      

    public void methodB () {
        ...
    }      
}
  • Comportamiento de propagación de transacciones
1. TransactionDefinition.PROPAGATION_REQUIRED:
   如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
 
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:
   创建一个新的事务,如果当前存在事务,则把当前事务挂起。
 
3. TransactionDefinition.PROPAGATION_SUPPORTS:
   如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
 
4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
   以非事务方式运行,如果当前存在事务,则把当前事务挂起。
 
5. TransactionDefinition.PROPAGATION_NEVER:
   以非事务方式运行,如果当前存在事务,则抛出异常。
 
6. TransactionDefinition.PROPAGATION_MANDATORY:
   如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
 
7. TransactionDefinition.PROPAGATION_NESTED:
   如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;
   如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
  • nivel de aislamiento de transacciones
1. @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读,
 不可重复读) 基本不使用
 
2. @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
 
3. @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
 
4. @Transactional(isolation = Isolation.SERIALIZABLE):串行化

Supongo que te gusta

Origin blog.csdn.net/qq_40406380/article/details/124380675
Recomendado
Clasificación