高并发环境下的hibernate事务提交问题

高并发环境下的hibernate事务提交问题,hibernate,Hibernate,我会详细解释我的问题我有以下课程 jms侦听器,它将侦听队列,并具有java 1.5线程池执行器来将mssage委托给线程(即RequestExecutor类) RequestExecutor(是一个可运行类),它将通过获取servicelayer对象来处理请求 服务类(saveStudent(),getStudent()) dao类。(saveStudent(),getStudent()) 考虑以下场景 请求1:保存学生的jms消息 jms收到消息并委托RequestExecutor保存学生

我会详细解释我的问题我有以下课程

  • jms侦听器,它将侦听队列,并具有java 1.5线程池执行器来将mssage委托给线程(即RequestExecutor类)
  • RequestExecutor(是一个可运行类),它将通过获取servicelayer对象来处理请求
  • 服务类(saveStudent(),getStudent())
  • dao类。(saveStudent(),getStudent())
  • 考虑以下场景

    请求1:保存学生的jms消息

  • jms收到消息并委托RequestExecutor保存学生
  • RequestExecutor调用ServiceLayer.saveStudent()并将消息发送回队列(此处服务层具有所有方法的事务边界)。所以,当消息发送到队列时,更改尚未提交到db
  • 请求2(该请求将在几毫秒后发出):获取学生的jms消息

  • jms收到消息并委托RequestExecutor获取学生(这是新线程)
  • RequestExecutor调用ServiceLayer.getStudent(),但在这里,第一个请求中所做的任何更改都尚未在db中更新,并返回null
  • 这两个线程之间存在一定的时间间隔(可能是几毫秒)。但在这里我可以看到db的变化。但它们对thread2不可见

    有人能解释这个问题吗

    谢谢,
    Ramki.

    这些线程在不同的JVM上运行吗

    当JVM上的一个进程向数据库提交一个事务时,我们也遇到了类似的问题,
    另一个JVM上的其他进程没有看到更改,因为它正在从一级或二级缓存中读取值。

    这正是2阶段提交解决的这类问题。对JMS队列的写入和在数据库中的保存应该是同一个全局2PC事务的一部分,以便两者都完成,或者都不完成。这将保证只有当且仅当用户已保存在数据库中时,第二个线程才会收到JMS消息


    JavaEEAppServers提供支持XA的(两阶段提交)事务管理器。如果您不是在Java EE appserver中运行,您可以自己在应用程序中集成一个,如Bitronix、Atomikos或其他独立事务管理器。

    听起来您在使用不同的资源(DB、JMS)实现业务事务,但不同步资源事务,即JMS和DB事务在不同的时间提交,导致系统状态不一致

    这是一个标准的体系结构问题。标准解决方案包括:

  • 使用xa事务。如果您在EJB容器中运行,容器管理的事务将默认使用xa事务(如果资源支持xa事务)。如果您不是在EJB容器中运行,那么可以使用分布式事务管理器(如atomikos)来利用xa事务
  • 仅使用单个资源,或者
  • 仅使用单个事务资源(数据库、放弃JMS),或
  • 让JMS实现使用相同的数据库来持久化消息。IIRC,如果ActiveMQ嵌入到VM中,它可以重用应用程序的数据库连接来持久化JMS消息,从而在数据库事务上实现负载

  • 谢谢你的快速回复。我正在使用WebSphereApplicationServer、spring和hibernate(hibernatetransaction管理器)。是否有可能采用您建议的使用上述技术的方法。如果可能的话,请给出一些示例代码。我很确定Websphere附带了一个支持JTA XA的事务管理器。您应该使用它而不是Hibernate TM。再见,再次感谢。如果可能,请发送jms+hiernate事务管理的示例配置。两个线程都运行在同一个JVM中。我们使用的是spring和hibernate(hibernateTransactionManager),我们使用的是WebSphereAppServer、spring和hibernate(hibernateTransactionManager用于事务管理)。如何在此场景中实现xa事务。如果可能,请提供一些示例代码。