【发布时间】:2009-11-19 12:11:38
【问题描述】:
在使用 Spring 时,在死锁或锁定超时异常时实现事务重启的最佳实践是什么(特别是 Spring 推荐的方法:声明性事务)?
谢谢,
阿萨夫
【问题讨论】:
标签: java spring transactions annotations deadlock
在使用 Spring 时,在死锁或锁定超时异常时实现事务重启的最佳实践是什么(特别是 Spring 推荐的方法:声明性事务)?
谢谢,
阿萨夫
【问题讨论】:
标签: java spring transactions annotations deadlock
我觉得 Spring 本身应该对这个问题有一个很好的答案(至少以文档的形式,或者某种重试拦截器)。唉,它没有。
可能处理重试的最佳方法(如果您想继续“声明”有关事物)是编写自己的拦截器实现,它将自动重试事务配置的次数。对于初学者,请研究 Spring 的 TransactionInterceptor,它管理声明式事务的开始/回滚/提交行为。如果您使用的是 Hibernate,请注意它如何处理 Hibernate 会话绑定/取消绑定到当前线程。
使用 Hibernate 时需要注意的事项:
session.clear() 是不够的。)MethodInterceptor.invoke() -- 传入此的MethodInvocation 实例可能是有状态的;在拦截器中使用它之前,您可能需要克隆它。【讨论】:
我推荐使用spring retry project中的org.springframework.retry.interceptor.RetryOperationsInterceptor类,配置如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"/>
但如果你仍然想自己实现它,example of AOP from spring documentation 是一个好的开始。
【讨论】:
没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重启或通知用户操作失败并要求明确的重试确认等。
在自动重启的情况下,我会使用 AOP。
【讨论】:
几年前我有同样的问题,最后写了 my own solution 作为 AOP 方面,最终在您的代码中看起来像这样:
@RetryTransaction
@Transactional
public void doSomething() {
....
}
【讨论】: