2

我在 Eclipse RAP 应用程序中使用 Hibernate。我使用 Hibernate 将数据库表映射到类,并且这些类具有延迟获取的属性(如果没有延迟获取这些属性,那么我可能最终会在第一次查询时将整个数据库加载到内存中)。我不同步数据库访问,所以有多个 HibernateSessions供用户使用,让 DBMS 进行事务隔离。这意味着获取数据的不同实例将属于不同的用户。有些事情如果用户更改了这些内容,那么我想在多个用户之间更新这些内容。目前我正在考虑session.refresh(object)在这些情况下使用 Hibernate 来刷新数据,但我不确定刷新多个对象时这将如何影响性能,或者它是否是正确的方法。

希望我的问题很清楚。我对这个问题的处理是好的,还是从根本上存在缺陷,或者我错过了什么?这类问题有通用解决方案吗?

我将不胜感激对此的任何评论。

4

2 回答 2

1

一般的解决方案是

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

如果每个事务都很短并且事务 A 将某个对象从 O 更新为 O',那么并发事务 B 在提交或回滚之前只会看到 O,而在 A 之后启动的任何其他事务都会看到 O',因为新会话开始了与交易。

于 2011-11-21T12:26:56.617 回答
1

我们维护的应用程序完全符合您的要求。是的,每个 session.refresh() 都会访问数据库,但是由于所有会话将同时刷新同一行,数据库服务器将从内存中回答所有这些查询。

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

对于我们的应用程序,我们在 RCP 上有大约 30 个用户,在 RAP 实例上有 10-100 个用户,它们都连接到同一个数据库后端(尽管通过 pgpool)。我们使用每个运行时都连接到的小型网络服务;当事务提交时,应用程序告诉该更改服务“表 T 的行 id X”已更改,然后将其传播到所有其他“更改订阅者”,甚至跨 JVM。

但是:确保 session.refresh() 在属于该会话的线程中被调用,可能是 RAP-Display 线程。不要从 Jobs 或其他无关线程调用 refresh()。

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

于 2013-01-15T15:22:08.810 回答