Java 如何在Spring中死锁/锁定超时时重新启动事务?
在使用Spring时,在出现死锁或锁超时异常时实现事务重启的最佳实践是什么(特别是Spring推荐的方法:声明性事务) 谢谢Java 如何在Spring中死锁/锁定超时时重新启动事务?,java,spring,transactions,annotations,deadlock,Java,Spring,Transactions,Annotations,Deadlock,在使用Spring时,在出现死锁或锁超时异常时实现事务重启的最佳实践是什么(特别是Spring推荐的方法:声明性事务) 谢谢 Asaf没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重新启动,或通知用户操作失败,并要求明确的重试确认等 我会在自动重启场景中使用AOP。我觉得Spring本身应该对这个问题有一个很好的答案(至少以文档的形式,或者某种重试拦截器的形式)。唉,事实并非如此 处理重试的最佳方法(如果您想继续对事情进行“声明性”处理)可能是编写自己的拦截器实
Asaf没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重新启动,或通知用户操作失败,并要求明确的重试确认等
我会在自动重启场景中使用AOP。我觉得Spring本身应该对这个问题有一个很好的答案(至少以文档的形式,或者某种重试拦截器的形式)。唉,事实并非如此 处理重试的最佳方法(如果您想继续对事情进行“声明性”处理)可能是编写自己的拦截器实现,该实现将自动重试事务配置的次数。首先,学习Spring的
TransactionInterceptor
,它管理声明性事务的开始/回滚/提交行为。如果您使用的是Hibernate,请注意它如何处理与当前线程的Hibernate会话绑定/解除绑定
使用Hibernate时要注意的事项:
- 您的“重试侦听器”应该确保取消绑定任何先前存在的线程绑定Hibernate会话,并重新绑定一个新会话。一旦从Hibernate/JDBC代码中抛出异常(例如死锁),相应的Hibernate会话就会中毒,需要丢弃。(
不够。)session.clear()
- 如果事务服务方法使用Hibernate会话对象作为方法参数,请小心。在重试时,当您重置Hibernate会话时,这些对象将被分离。如果服务方法假定它们已连接(例如,如果它们使用在服务方法中访问的延迟加载属性,或者如果您尝试保存它们,等等),则需要重新连接它们。一般来说,最好不要将Hibernate对象用作事务性服务方法的参数
- 您将实现
——传递给它的MethodInterceptor.invoke()
实例可能是有状态的;在拦截器中使用它之前,您可能需要克隆它MethodInvocation
是一个很好的开始。几年前我也遇到过同样的问题,最后我将其作为AOP方面来编写,最终在代码中显示如下:
@RetryTransaction
@Transactional
public void doSomething() {
....
}
感谢您提及spring重试项目。
@RetryTransaction
@Transactional
public void doSomething() {
....
}