当使用Spring(特别是Spring推荐的声明式事务)时,如何在死锁或锁定超时异常发生时实施事务重启的最佳做法是什么?
谢谢,
Asaf
当使用Spring(特别是Spring推荐的声明式事务)时,如何在死锁或锁定超时异常发生时实施事务重启的最佳做法是什么?
谢谢,
Asaf
我觉得春季本身应该有一个好的答案来回答这个问题(至少以文档的形式,或是某种重试拦截器的形式)。然而,它没有。
如果你想继续保持“声明式”的风格处理重试,最好的方法可能是编写自己的拦截器实现,该实现将自动重试事务一定次数。首先,学习Spring的TransactionInterceptor
,该拦截器管理声明性事务的开始/回滚/提交行为。如果正在使用Hibernate,请注意其如何处理Hibernate会话与当前线程的绑定/解绑。
如果您正在使用Hibernate,需要注意以下事项:
session.clear()
不足够)MethodInterceptor.invoke()
- 传递给此方法的MethodInvocation
实例可能具有状态;在拦截器中使用它之前可能需要进行克隆。我建议使用spring retry 项目 中的类org.springframework.retry.interceptor.RetryOperationsInterceptor
,并像这样配置:
<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"/>
但是如果您仍希望自己实现它,来自Spring文档的AOP示例是一个很好的开始。
几年前我也有同样的问题,并最终编写了自己的解决方案,作为一个AOP切面,在您的代码中看起来像这样:
@RetryTransaction
@Transactional
public void doSomething() {
....
}
没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重启或通知用户有关操作失败并要求明确的重试确认等。
如果是自动重启方案,我会使用AOP。