El motivo del error de la transacción de primavera (invocando su propia solución de motivo)

1. El motor de la base de datos no admite transacciones
. Tome MySQL como ejemplo. Su motor MyISAM no admite operaciones de transacción. InnoDB es el motor que admite transacciones. Generalmente, InnoDB se utiliza para admitir transacciones.
2. No está administrado por Spring .

// @Service
public class OrderServiceImpl implements OrderService {
    
    

    @Transactional
    public void updateOrder(Order order) {
    
    
        // update order
    }
}

Si la
anotación @Service está comentada en este momento , esta clase no se cargará como un Bean, entonces esta clase no será administrada por Spring y la transacción naturalmente dejará de ser válida.
3. El método no es público, lo cual
probablemente significa que
@Transactional solo puede Se usa para métodos públicos, de lo contrario la transacción no fallará. Si desea usarlo para métodos no públicos, puede habilitar el
modo proxy de AspectJ.
4. Problema de auto-llamada
Veamos dos ejemplos:

@Service
public class OrderServiceImpl implements OrderService {
    
    

    public void update(Order order) {
    
    
        updateOrder(order);
    }

    @Transactional
    public void updateOrder(Order order) {
    
    
        // update order
    }

}

No hay una anotación @Transactional en el método de actualización, y se llama al método updateOrder con la anotación @Transactional. ¿Funciona la transacción en el método updateOrder?
Veamos de nuevo el siguiente ejemplo:

@Service
public class OrderServiceImpl implements OrderService {
    
    

    @Transactional
    public void update(Order order) {
    
    
        updateOrder(order);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateOrder(Order order) {
    
    
        // update order
    }

}

Esta vez, @Transactional se agrega al método de actualización y REQUIRES_NEW se agrega a updateOrder para iniciar una nueva transacción. ¿Funcionará la transacción recién abierta?
La respuesta a estos dos ejemplos es: ¡no funciona!
Debido a que llaman a sus propios métodos, llaman a sus propios métodos en lugar de las clases proxy de Spring. De forma predeterminada, la transacción solo tendrá efecto cuando la transacción se llame externamente. Este también es un problema clásico del que se habla a menudo.
Solución:

@Resource
private UpdateOrder updateOrder;
 public void update(Order order) {
    
    
        updateOrder.updateOrder(order);
    }

Esto es lo mismo que Spring @Sync requiere generación de proxy

https://www.cnblogs.com/jtlgb/p/11124770.html

5. La fuente de datos no tiene un administrador de transacciones configurado

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

6, no admite asuntos

@Transactional(propagation = Propagation.NOT_SUPPORTED)

7. Si se come la excepción,
try catch no lanza una excepción Si la excepción se come y luego no se lanza, ¿cómo se puede revertir la transacción?
8. El tipo de excepción es incorrecto.

 @Transactional
  public void updateOrder(Order order) 

Esta transacción tampoco es efectiva, porque la reversión predeterminada es: RuntimeException, si desea activar la reversión de otras excepciones, debe configurarla en la anotación, como:

@Transactional(rollbackFor = Exception.class)

Esta configuración está limitada a la clase de excepción Throwable y sus subclases.

Referencia: https://zhuanlan.zhihu.com/p/101396825

Supongo que te gusta

Origin blog.csdn.net/qq_38893133/article/details/110819461
Recomendado
Clasificación