2009-11-19 14 views

Respuesta

4

No hay una respuesta universal, ya que depende de aspectos específicos de la aplicación. Por ejemplo, es posible que desee realizar una operación transaccionada automática reiniciar o notificar al usuario sobre la falla de operación y solicitar una confirmación de reintento explícita, etc.

Usaría el AOP en caso de un escenario de reinicio automático.

15

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.
7

recomiendo el uso de la clase org.springframework.retry.interceptor.RetryOperationsInterceptor desde el reintento de primavera project, configurado como this:

<aop:config> 
    <aop:pointcut id="transactional" expression="execution(* com...*Service.remoteCall(..))" /> 
    <aop:advisor pointcut-ref="transactional" advice-ref="retryAdvice" order="-1"/> 
</aop:config> 

<bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor"/> 

Pero si aún desea implementar por sí mismo, el example of AOP from spring documentation es un buen comienzo.

+2

Gracias por mencionar proyecto de primavera-reintento. –

4

que tenían la misma pregunta hace varios años y terminó escribiendo my own solution como un aspecto de AOP, que termina pareciéndose a esto en su código:

@RetryTransaction 
    @Transactional 
    public void doSomething() { 
     .... 
    } 
+0

El enlace está muerto. –

+0

Gracias, enlace actualizado. – Archie

+0

Oh wow. Muchas gracias. Definitivamente voy a echarle un vistazo. –

Cuestiones relacionadas