1

我希望有人可以为我澄清以下场景。

据我了解,当您从休眠状态请求“行”时,例如:

User user = UserDao.get(1);

我知道内存中有 id=1 的用户。

在 Web 应用程序中,如果 2 个网页同时请求和加载用户,然后都更新用户对象的属性,会发生什么情况?例如:

user.pageViews += 1; // the value is current 10 before the increment
UserDao.update(user);

这将使用内存中的值(两个请求的值都是 10),还是使用数据库中的值?

4

2 回答 2

2

您必须为这两个用户使用两个休眠会话。这意味着内存中有两个对象实例。如果您只使用一个休眠会话(以及内存中的一个对象实例),那么结果是不可预测的。

在并发更新的情况下,第二次更新获胜。第一次更新的值被第二次更新覆盖。为避免第一次更新丢失,您通常使用版本列(请参阅休眠文档),然后第二次更新会收到一个错误,您可以捕获并对其做出反应(例如,错误消息“您的记录已在同时。请重新加载。”这允许第二个用户对修改的记录重新进行修改,以确保他的修改不会丢失。

在页面浏览计数器的情况下,就像在您的示例中一样,作为一种不同的解决方案,您可以编写一个同步的方法来按顺序计算页面浏览量。

于 2012-09-25T15:28:27.870 回答
1

默认情况下,该in memory值用于更新。

在下文中,我假设您要实现自动页面查看计数器,而不是User在 Web 用户界面中修改。如果你想看看Hibernate 乐观锁定

因此,假设您在计算页面浏览量时需要 100% 的准确度,您可以User在修改实体pageView值以获得对表行的排他性时锁定您的实体:

Session session = ...
Transaction tx = ...

session.lock(user, LockMode.UPGRADE);
user.increasePageViews();

tx.commit();
session.close();

LockMode.UPGRADESELECT ... FOR UPDATE在您的数据库中转换,因此请注意尽可能少地维护锁定,以免影响应用程序的可伸缩性。

于 2012-09-25T15:47:58.127 回答