【问题标题】:Hibernate: Find just persisted object in different thread休眠:在不同的线程中查找刚刚持久的对象
【发布时间】:2014-09-09 11:02:44
【问题描述】:

我的应用程序中有多个线程 - 其中一个正在等待在数据库中的某些更改中得到通知。我的问题是,一旦我持久化某个对象并通知另一个线程 - 当它在数据库中查询自上次更改以来的新对象时,找不到持久化的对象。

  @Transactional()
  public void persistMyEntity() {
      // persisting and notifying from first thread
      Entity myEntity = new Entity();
      em.persist(myEntity)
      em.flush();
      someOtherBean.notifyChange();
  }
  ...

以下 bean 应该被唤醒:

  public class SomeOtherBean {

      public void notifyChange() {
          currentThread.interrupt();
      }


      public void run() {
          currentThread = Thread.currentThread();

          while(true) {
              ...
              try {
                  Thread.sleep(VERY_LONG_TIME);
              } catch (InterrupedExcdeption e) {
                  // we don't care
              }

              findNewPersistedObjects();
              // nothing is found
          }
      }
  }

如果我重新启动线程,它会正确找到新对象。

编辑:拆分事务方法没有任何区别:

  public void persistMyEntity() {
      proxy(this).persistMyEntityInternal();
      someOtherBean.notifyChange();
  }

  @Transactional
  public void persistMyEntityInternal() {
      // persisting and notifying from first thread
      Entity myEntity = new Entity();
      em.persist(myEntity)
      em.flush();
  }
  ...

【问题讨论】:

    标签: java multithreading hibernate


    【解决方案1】:

    你的问题是事务分界。

    您在事务完成之前通知您的其他线程。数据库中的数据只有在创建数据的事务结束时才能查询(有提交)(有些数据库有一些例外,但我不会对此进行深入探讨)。

    要解决您的问题,您必须在从另一个线程查询之前提交您的事务。

    【讨论】:

    • 我如何实际提交事务? em.flush 在一个用@Transactional 注释的方法中。
    • @Vojtěch 在离开方法时提交事务。因此,您必须在带有事务注释的方法之后查询方法。
    【解决方案2】:

    您可以使用TransactionSynchronizationManager 注册TransactionSynchronization。这允许您在成功提交 trx 时被回调。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      相关资源
      最近更新 更多