4

我有一个用 Tapestry5 (java webframework) 和 Hibernate 制作的 web 应用程序。现在我正在尝试添加乐观锁定。所以我添加了一个版本属性并且乐观锁定工作,所以这很容易和快速。

但是由于我的 Web 应用程序使用“每个请求的会话”模式,我不确定利用这种乐观锁定的最佳方式是什么。

怎么了:

UserA 使用加载了 entityA(版本 1)的值的表单打开页面。

UserB 使用加载了来自 entityA(版本 1)的值的表单打开页面。

UserA 更改一些值并提交表单。-> 新请求检索 entityA(版本 1)并提交更改(entityA 现在是版本 2)

UserB 更改一些值并提交表单。-> 新请求检索 entityA(版本2)并提交更改(entityA 现在是版本 3)

应该发生什么

不应提交 UserB 的更改。但是由于 session-per-request 模式,Hibernate 的乐观锁定错误可能发生的时间窗口减少到仅从提交后的新请求到提交的时间跨度,这不是预期的结果。

可能的解决方案

经过一番研究,我发现了以下内容:

  • 使用实体版本向表单添加隐藏字段

我可以在提交之前使用这个值来设置实体的版本,但是 Hibernate 文档不建议设置这个值。此外,它仅在实体被分离和重新连接时才有效,因为否则 Hibernate 会忽略手动设置的版本值。

其次,我可以使用此版本值进行手动检查,当呈现表单时,版本是否与提交请求中加载的实体版本相同。如果需要,然后自己抛出一个 OptimisticLockingException。

  • 将分离的实体放入 HttpSession 中,因此我不必在提交时再次加载它

结论

这些方法有效,但对我来说似乎不太实用并且容易出错。所以我想知道其他人如何实现这个问题。

4

2 回答 2

1

我最终实现了以下内容:

  • 使用实体版本向表单添加隐藏字段
  • 使用表单 dto 对象
  • 将这些 dto 对象附加到 httpsession(跨多个请求的会话状态)
  • dto 和实际对象之间的手动版本检查
于 2013-02-18T16:40:20.507 回答
0

When you detach a persistent entity just to transfer it to the web layer, as an example create DTO to transfer objects to the web layer. in that case we will transform Entity objects into the DTO objects using getters and setters.

If you need to maintain the concurrency control with Optimistic locking, you have to maintain the version number in your application (it's different from manually setting the version number). Otherwise there is no way we can instruct hibernate what was the old version of the loaded record. In hibernate documentation it says "Keep the disconnected Session close to the persistence layer. Use an EJB stateful session bean to hold the Session in a three-tier environment. Do not transfer it to the web layer, or even serialize it to a separate tier, to store it in the HttpSession. ", But all the environments do not have EJB stateful session beans in business layer. In that case we have to maintain the version number.

As long as you can maintain the version, you do not need to manually check the version in the program, it is efficient if you let hibernate to do that, because you cannot predict the depth of your object hierarchy.

So what you can do is you have to set the version again to the persistent entity if you use detached objects in the web layer, Then hibernate will take care of the Cocurrency Control.

于 2012-12-15T05:05:13.483 回答