我有一个用Tapestry5 ()和Hibernate开发的web应用程序。现在,我试图添加乐观锁定。因此,我添加了一个version属性,并且乐观锁定工作,因此这是简单和快速的。
但是,由于我的web应用程序使用“按请求会话”模式,我不确定使用这种乐观锁定的最佳方式是什么。
发生了什么:
UserA用表单打开页面,其中包含来自entityA的值(版本1)。
UserB用表单打开页面,其中包含来自entityA的值(版本1)。
UserA更改一些值并提交表单。->新请求检索entityA (版本1)并提交更改(entityA现在是版本2)
UserB更改一些值并提交表单。->新请求检索entityA (版本2)并提交更改(entityA现在是版本3)
应该发生什么
不应提交UserB的更改。但是,由于每次请求的会话模式,Hibernate的乐观锁定错误可能发生的时间窗口从提交到提交后的新请求减少到新请求的时间周期,这不是期望的结果。
可能的解决方案
经过一些研究,我发现如下:
我可以使用这个值在提交之前设置实体的版本,但是Hibernate文档不建议设置这个值。而且,只有当实体被分离和重新连接时,它才能工作,因为否则Hibernate会忽略手动设置的版本值。
其次,我可以使用这个版本值来手动检查表单呈现时的版本是否与在submit上加载的实体的版本相同。如果需要的话,自己抛出一个OptimisticLockingException。
结论
这些方法有效,但在我看来不太实用,而且容易出错。所以我想知道其他人是如何实现这个问题的。
发布于 2013-02-18 16:40:20
最后,我实现了以下内容:
发布于 2012-12-15 05:05:13
当您分离一个持久实体只是为了将其传输到web层时,例如创建DTO将对象传输到web层。在这种情况下,我们将使用getter和setter将实体对象转换为DTO对象。
如果需要使用乐观锁定来维护并发控制,则必须在应用程序中维护版本号(与手动设置版本号不同)。否则,我们就无法指示hibernate加载记录的旧版本。在hibernate文档中,它说“保持断开连接的会话接近持久层。使用EJB有状态会话bean在三层环境中保存会话。不要将它传输到web层,甚至不要将它序列化到单独的层,以存储在HttpSession中。”但是所有的环境都在业务层中没有EJB有状态的会话bean。在这种情况下,我们必须维护版本号。
只要您能够维护版本,您就不需要手动检查程序中的版本,如果让hibernate来进行检查是有效的,因为您无法预测对象层次结构的深度。
因此,如果在web层中使用分离对象,则必须再次将版本设置为持久性实体,然后hibernate将负责Cocurrency控件。
https://stackoverflow.com/questions/13720394
复制相似问题