2011-11-20 61 views
2

我在Eclipse RAP应用程序中使用Hibernate。我有数据库表与Hibernate映射到类,这些类具有懒惰地获取的属性(如果这些没有被懒惰地提取,那么我可能会最终将我的第一个查询加载到内存中的整个数据库)。我不同步数据库访问,因此对于用户有多个Hibernate Sessions,并让DBMS执行事务隔离。这意味着获取数据的不同实例将属于不同的用户。有些事情,如果用户改变这些东西,那么我想更新多个用户。目前我正考虑在这些情况下使用Hibernate session.refresh(object)来刷新数据,但我不确定刷新多个对象时这会如何影响性能,或者是否是正确的方法。休眠和多线程,同步多个用户之间的变化

希望我的问题清楚。我对这个问题的接受程度还可以,或者是根本上有缺陷,还是我错过了一些东西?这种问题是否有一个通用的解决方案?

我希望对此有任何意见。

回答

1

一般的解决方法是

  • 有交易尽可能短
  • 到会话的生命周期链接到交易周期(这是默认的:当事务被提交或回滚的会话关闭back)
  • 使用乐观锁定并发来避免两个事务同时更新同一个对象。

如果每笔交易很短,事务A从0到O更新一些对象,然后并发事务B将只能看到O键,直到它提交或回滚,而任何其他交易开始后,会看到O' ,因为新的会话以交易开始。

1

我们维护一个应用程序,完全按照您要完成的操作。是的,每个session.refresh()都会触发数据库,​​但由于所有会话将同时刷新同一行,因此数据库服务器将从内存中回答所有这些查询。

您仍然需要解决的唯一问题是如何传播某些信息已发生变化,并且需要重新加载到所有其他会话,甚至可能会重新加载到其他主机上的会话。

对于我们的应用程序,我们在RCP上有大约30个用户,在RAP实例上有10-100个用户都连接到相同的DB后端(尽管通过pgpool)。我们使用每个运行时连接到的小型网络服务;当一个事务提交时,应用程序告诉这个变更服务“表T的行标识X”已经改变,然后它被传播到所有其他的“变更订户”,即使在JVM上也是如此。

但是:确保在属于该会话的线程内调用session.refresh(),可能是RAP显示线程。不要从作业或其他不相关的线程调用refresh()。

只要你没有大量的用户在短时间内更新大量的行,我想你不必担心性能。