Creo que Spring debería tener una buena respuesta a esta pregunta (en forma de documentación, como mínimo, o un interceptor de reintentos de algún tipo). Por desgracia, no es así.
Probablemente la mejor manera de manejar los reintentos (si quiere continuar siendo "declarativa" sobre las cosas) es escribir su propia implementación de interceptor que automáticamente reintentará la transacción una cantidad de veces configurada. Para empezar, estudia Spring TransactionInterceptor
, que gestiona el comportamiento de inicio/retroceso/confirmación para las transacciones declarativas. Si está utilizando Hibernate, observe cómo maneja la vinculación/desvinculación de sesión de Hibernate con el Thread actual.
Cosas a tener en cuenta si está usando Hibernate:
- Su "reintentar interceptor" debe estar seguro para desenlazar cualquier sesión de Hibernate hilo unido pre-existente y volver a enlazar una nueva. Una vez que se lanza una excepción (por ejemplo, interbloqueo) desde el código de Hibernate/JDBC, la sesión de Hibernate correspondiente se envenena y debe descartarse. (
session.clear()
no es suficiente).
- Tenga cuidado si sus métodos de servicio transaccionales usan objetos de sesión de Hibernate como parámetros de método. Cuando vuelva a intentarlo, cuando reinicie su sesión de Hibernate, estos objetos se separarán. Tendrá que volver a conectarlos si el método de servicio supone que están adjuntos (por ejemplo, si usan propiedades cargadas perezosas a las que se acceda en el método de servicio, o si intenta guardarlas, etc.) En general, es mejor si no use objetos de Hibernate como parámetros para los métodos de servicio transaccional.
- Implementarás
MethodInterceptor.invoke()
- la instancia que se transfiere a esto puede ser con estado; Es posible que deba clonarlo antes de usarlo en el interceptor.
Gracias por mencionar proyecto de primavera-reintento. –