Hibernate和多线程,同步多个用户之间的更改
我在 Eclipse RAP 应用程序中使用 Hibernate。我将数据库表映射到 Hibernate 的类,并且这些类具有延迟获取的属性(如果这些属性不是延迟获取的,那么我最终可能会在第一次查询时将整个数据库加载到内存中)。我不同步数据库访问,因此用户有多个 Hibernate 会话,并让 DBMS 进行事务隔离。这意味着获取的数据的不同实例将属于不同的用户。如果用户更改了某些内容,那么我想在多个用户之间更新这些内容。目前,我正在考虑在这些情况下使用 Hibernate session.refresh(object)
来刷新数据,但我不确定刷新多个对象时这将如何影响性能,或者这是否是正确的方法。
希望我的问题很清楚。我解决问题的方法是否正确,或者是否存在根本缺陷,或者我是否遗漏了某些内容?此类问题有通用的解决方案吗?
如果对此有任何评论,我将不胜感激。
I am using Hibernate in an Eclipse RAP application. I have database tables mapped to classes with Hibernate and these classes have properties that are fetched lazily (If these weren't fetched lazily then I would probably end up loading the whole database into memory on my first query). I do not synchronize database access so there are multiple Hibernate Sessions
for the users and let the DBMS do the transaction isolation. This means different instances of fetched data will belong to different users. There are things that if a user changes those things, then I would like to update those across multiple users. Currently I was thinking about using Hibernate session.refresh(object)
in these cases to refresh the data, but I'm unsure how this will impact performance when refreshing multiple objects or if it's the right way to go.
Hope my problem is clear. Is my approch to the problem OK or is it fundamentally flawed or am I missing something? Is there a general solution for this kind of problem?
I would appreciate any comments on this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般的解决方案是
如果每个事务都很短,并且事务 A 将某个对象从 O 更新为 O',那么并发事务 B 在提交或回滚之前只会看到 O,而在 A 之后启动的任何其他事务都会看到 O',因为新会话开始与交易。
The general solution is
If each transaction is very short and transaction A updates some object from O to O', then concurrent transaction B will only see O until it commits or rolls back, and any other transaction started after A will see O', because a new session starts with the transaction.
我们维护的应用程序完全可以完成您想要完成的任务。是的,每个 session.refresh() 都会访问数据库,但由于所有会话将同时刷新同一行,因此数据库服务器将从内存中回答所有这些查询。
您仍然需要解决的唯一问题是如何将某些内容已更改并需要重新加载的信息传播到所有其他会话,甚至可能传播到不同主机上的会话。
对于我们的应用程序,我们在 RCP 上有大约 30 个用户,在 RAP 实例上有 10-100 个用户,它们都连接到同一个数据库后端(尽管通过 pgpool)。我们使用每个运行时都连接到的小型网络服务;当事务提交时,应用程序告诉此更改服务“表 T 的行 id X”已更改,然后将其传播到所有其他“更改订阅者”,甚至跨 JVM。
但是:请确保在属于该会话的线程(可能是 RAP-Display 线程)内调用 session.refresh()。不要从作业或其他不相关的线程中调用refresh()。
只要您没有大量用户在短时间内更新大量行,我想您就不必担心性能。
We maintain an application that does exactly what you are trying to accomplish. Yes, every session.refresh() will hit the database, but since all sessions will refresh the same row at the same time, the DB server will answer all of these queries from memory.
The only thing that you still need to solve is how to propagate the information that something has changed and needs reloading to all the other sessions, possibly even to sessions on a different host.
For our application, we have about 30 users on RCP and 10-100 users on RAP instances that all connect to the very same DB backend (though through pgpool). We use a small network service that every runtime connects to; when a transaction commits, the application tells this change service that "row id X of table T" has changed and this is then propagated to all other "change subscribers", even across JVMs.
But: make sure that session.refresh() is called within the Thread that belongs to that session, possibly the RAP-Display thread. Do not call refresh() from Jobs or other unrelated threads.
As long you don't have a large number of users updating big counts of rows in short time, I guess you won't have to worry about performance.