Transacción revertida porque se marcó como solo revertir

Transaction Rolled Back Because It Has Been Marked

Transacción revertida porque se marcó como solo revertir

problema

El programa ejecuta una excepción org.springframework.transaction.UnexpectedRollbackException: Transacción revertida porque se marcó como solo reversión, la pila de registro de errores no puede encontrar rastros obvios.

Restauración de escena

Entrada:

|_+_|

Llamada interna:

|_+_| |_+_|

la razón

Gestión de transacciones de Spring, un método habilitado para transacciones que propaga transacciones cuando se llama a otro método de transacción. El mecanismo de propagación predeterminado para @Transactional es PROPAGATION_REQUIRED.



Comportamiento comunicativo sentido
PROPAGATION_REQUIRED Indica que el método actual debe estar ejecutándose en una transacción. Si existe la transacción actual, el método se ejecutará en esa transacción. De lo contrario, se iniciará una nueva transacción.

Entonces, cuando se ejecuta el método de llenado, las transacciones sincronizadas se fusionan en la transacción completa. Cuando la factura síncrona es anormal, el try catch la detecta y no se lanza. Sin embargo, la transacción aún se revertirá. Cuando se ejecuta la reversión al método doSetRollbackOnly de la clase DataSourceTransactionManager, se establece rollbackOnly = true.



|_+_| |_+_|

Dado que se detecta la excepción, no se bloquea toda la transacción. Después de que se ejecuta toda la transacción, se ejecuta el compromiso de confirmación. Cuando se ejecuta el método isGlobalRollbackOnly de la clase DefaultTransactionStatus, se considera que rollbackOnly es verdadero, luego se realiza la reversión y se imprime el registro del error. 'Transacción revertida porque se marcó como solo reversión'.



|_+_| |_+_|

Algunos pensando

  1. Una transacción puede completar una transacción
  2. Cuando la transacción se anida y se propaga, try catch se usa menos y la reversión se revierte.
  3. Cuando una transacción está anidada, puede especificar el modo de propagación. Puede especificar la transacción interna como @Transactional (propagation = Propagation.NESTED) o @Transactional (propagation = Propagation.PROPAGATION_REQUIRED_NEW) según sus necesidades.
Comportamiento comunicativo sentido
PROPAGATION_REQUIRED_NEW Indica que el método actual debe estar ejecutándose en su propia transacción. Se iniciará una nueva transacción. Si hay una transacción actual, la transacción actual se suspenderá durante la ejecución del método.
PROPAGATION_NESTED Indica que si ya existe una transacción, el método se ejecutará en una transacción anidada. Las transacciones anidadas se pueden confirmar o deshacer independientemente de la transacción actual. Si la transacción actual no existe, su comportamiento es el mismo que PROPAGATION_REQUIRED. Tenga en cuenta que el soporte de los proveedores para este tipo de comportamiento de comunicación es diferente. Puede consultar la documentación del administrador de recursos para confirmar si admiten transacciones anidadas.