Java 如何在Spring中死锁/锁定超时时重新启动事务?

Java 如何在Spring中死锁/锁定超时时重新启动事务?,java,spring,transactions,annotations,deadlock,Java,Spring,Transactions,Annotations,Deadlock,在使用Spring时,在出现死锁或锁超时异常时实现事务重启的最佳实践是什么(特别是Spring推荐的方法:声明性事务) 谢谢 Asaf没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重新启动,或通知用户操作失败,并要求明确的重试确认等 我会在自动重启场景中使用AOP。我觉得Spring本身应该对这个问题有一个很好的答案(至少以文档的形式,或者某种重试拦截器的形式)。唉,事实并非如此 处理重试的最佳方法(如果您想继续对事情进行“声明性”处理)可能是编写自己的拦截器实

在使用Spring时,在出现死锁或锁超时异常时实现事务重启的最佳实践是什么(特别是Spring推荐的方法:声明性事务)

谢谢


Asaf没有通用的答案,因为它取决于应用程序的具体情况。例如,您可能希望执行自动事务操作重新启动,或通知用户操作失败,并要求明确的重试确认等


我会在自动重启场景中使用AOP。

我觉得Spring本身应该对这个问题有一个很好的答案(至少以文档的形式,或者某种重试拦截器的形式)。唉,事实并非如此

处理重试的最佳方法(如果您想继续对事情进行“声明性”处理)可能是编写自己的拦截器实现,该实现将自动重试事务配置的次数。首先,学习Spring的
TransactionInterceptor
,它管理声明性事务的开始/回滚/提交行为。如果您使用的是Hibernate,请注意它如何处理与当前线程的Hibernate会话绑定/解除绑定

使用Hibernate时要注意的事项:

  • 您的“重试侦听器”应该确保取消绑定任何先前存在的线程绑定Hibernate会话,并重新绑定一个新会话。一旦从Hibernate/JDBC代码中抛出异常(例如死锁),相应的Hibernate会话就会中毒,需要丢弃。(
    session.clear()
    不够。)
  • 如果事务服务方法使用Hibernate会话对象作为方法参数,请小心。在重试时,当您重置Hibernate会话时,这些对象将被分离。如果服务方法假定它们已连接(例如,如果它们使用在服务方法中访问的延迟加载属性,或者如果您尝试保存它们,等等),则需要重新连接它们。一般来说,最好不要将Hibernate对象用作事务性服务方法的参数
  • 您将实现
    MethodInterceptor.invoke()
    ——传递给它的
    MethodInvocation
    实例可能是有状态的;在拦截器中使用它之前,您可能需要克隆它

我建议使用spring重试中的类org.springframework.retry.interceptor.RetryOperationsInterceptor,配置如下:


是一个很好的开始。

几年前我也遇到过同样的问题,最后我将其作为AOP方面来编写,最终在代码中显示如下:

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

感谢您提及spring重试项目。
  @RetryTransaction
  @Transactional
  public void doSomething() {
      ....
  }