Java 关于spring事务管理重新设计的建议

Java 关于spring事务管理重新设计的建议,java,spring,hibernate,jpa-2.0,Java,Spring,Hibernate,Jpa 2.0,我将试着描述我试图解决的问题。我意识到我开发的一个应用程序的spring事务管理实现得很差。我对DAO接口方法(CRUD)上定义的事务使用声明性方法,而不是服务层方法。它是一个web应用程序,可以进行某种消息处理,多个线程同时对同一个消息实例进行操作。以下是典型顺序中的步骤: 消息在T1(事务1)中创建并放入出站队列。T1被终止 消息由另一个线程从队列中获取,随发送时间和一些附加信息一起发送和更新。设置消息对象的属性并调用dao.update(m),t2开始 在t2提交之前,接收到传递报告,Tr

我将试着描述我试图解决的问题。我意识到我开发的一个应用程序的spring事务管理实现得很差。我对DAO接口方法(CRUD)上定义的事务使用声明性方法,而不是服务层方法。它是一个web应用程序,可以进行某种消息处理,多个线程同时对同一个消息实例进行操作。以下是典型顺序中的步骤:

  • 消息在T1(事务1)中创建并放入出站队列。T1被终止
  • 消息由另一个线程从队列中获取,随发送时间和一些附加信息一起发送和更新。设置消息对象的属性并调用dao.update(m),t2开始
  • 在t2提交之前,接收到传递报告,Tread3开始处理相同的消息对象,方法是在db中找到它(保存在步骤1中),更新它的状态属性并调用dao.upate(m),以便t3在t2仍在进行时启动
  • 另一个线程(线程4)通过在t4中再次更改同一消息对象的状态来进一步处理该消息对象
  • 不时出现的结果是t2的更改丢失,发送时间为空(以db为单位)。 我需要帮助找出如何改进应用程序设计,并通过防止并发处理同一消息来消除此问题

  • 我应该专注于事务重新设计(在服务级别而不是dao上使用它)和使用可序列化隔离级别(或其他)吗

  • 我应该使用JPA实体管理器锁定吗


  • 应用程序使用Spring3和JPA2实现hibernate。

    是的,我会将事务转移到服务级别,但我会重新考虑整个设计,看看是否可以将整个流程整合到一个线程中。如果我没记错的话,Spring的事务管理是基于线程的——我怀疑您是否能够拥有跨线程的事务

    此外,如果可能的话,尽量简化事情,以便只访问数据库一次。 如果确实需要四个单独的更新,请在同一线程的同一事务中顺序运行它们。否则,您将不会有一个很好的时间尝试让事务工作

    显式锁定也会带来伤害——你很可能会因此而陷入死锁

    编辑:针对OP的评论:

    我建议找到一种将T3更新与T2更新分开的方法,并让T2事务在执行T3更新之前提交

    可能将传递报告放在消息队列中。 然后想出一个策略,在T3中查找项目并进行更新(如果它存在),或者稍后重试(如果它不存在)


    如果您知道从收到交付报告到T2事务结束之间有一个最小或平均时间量,那么您可以将该延迟量构建到交付收据的处理中,以创建T3更新。

    消息是如何发送的?JMS?网络服务?另外您能否将此部分作为全局分布式事务的一部分(对于JMS)?如果不是,您不应该在T2完成后发送消息,从而确保在接收到交付报告时T2已结束吗?消息通过第三方web服务发送。T2无法在发送邮件之前执行,因为邮件已用发送结果更新。很遗憾,我无法避免多个线程,因为传递报告是通过HTTP接收的。我做了一些关于事务隔离的研究,发现RDMS负责事务处理,而不是spring。但我想知道如果我为T2和T3设置可序列化隔离,会发生什么?T2将获取表上的锁,当t3尝试这样做时,它会等待锁释放还是失败并抛出异常?