我正在使用Spring / Hibernate / ZK。在一个选项卡中,我从DB获取对象以供用户编辑,但第二个用户可以打开相同的选项卡和相同的对象进行编辑。我想通知第二个用户的消息,例如“此对象已经打开”并隐藏按钮以进行保存。第二个用户可以看到从DB到此对象的当前数据,但不能对他进行编辑。是否有办法检查此会话对象或其他方式。
答案 0 :(得分:1)
@Version
字段。它保存对象版本,该版本在每次更新操作后递增。如果第二个用户在第一个已保存的对象之后保存对象,它将抛出您可以在代码中处理的OptimisticLockException
。更多关于乐观和悲观锁定的信息:Chapter 5. Locking。相关讨论:Hibernate Automatic Versioning和When to use @Version and @Audited in Hibernate? 答案 1 :(得分:1)
最好的解决方案是使用带有版本控制的乐观并发控制,当Hibernate抛出并发更新问题时,由于同一行正在两个事务中更新,然后使用以下策略之一
First Wins Strategy并不是一个好的解决方案,因为它会导致更新丢失,用户会因为失去他的所有工作而感到沮丧。
通过Last Wins策略,用户之一将收到错误消息,表明您正在处理陈旧数据并再次启动您的交易。通过这种方式,用户也会感到沮丧,因为他现在需要从头开始重新开始操作,但他的更改不会丢失。
而是使用Merge冲突的更新策略,当Hibernate使用新数据抛出Stale对象异常重新加载屏幕时,用户将看到更新的结果并允许他继续使用最新数据。在这个用户中,更改不会丢失,用户也不会收到错误消息,只是他的屏幕重新加载了新数据,他可以决定是否继续。
您可以举例说明任何电子商务网站,您将获得最终胜利策略或合并冲突更新策略的结果。两个用户可以从一个项目开始,但是一个用户将在最后一个屏幕中获得该项目不是库存的消息。
答案 2 :(得分:1)
其他答案主要是查看数据库,但如果所有用户使用相同的zk应用程序访问数据库,您可以跟踪Composer
或ViewModel
中打开的对象(具体取决于您是否使用MVC或MVVM;我只是称它为控制器)。
您的控制器需要static
目前已修改的对象列表。如果用户请求打开不在列表中的对象,则一切正常,控制器将启用字段和保存按钮。否则,这些将被禁用和/或您显示一条消息。
棘手的部分是清除该列表中的对象。如果用户按下保存按钮,则只需从列表中删除该对象。但是,如果用户没有关闭选项卡或他们的会话只是超时,该怎么办?在这种情况下,您需要一个回调或一个定期检查屏幕是否仍然打开的机制。
您可以通过向随机ping的选项卡添加zk计时器来实现此目的,并更新静态列表中的时间戳(因此将其设为地图)。如果新用户尝试编辑该对象,请检查上一个时间戳的年龄。如果它足够大(即前一个用户保存或放弃了屏幕),允许他们编辑它。
但是,如果用户只是保持屏幕打开,你必须考虑该怎么做。他们允许多长时间锁定物体?这也是Microsoft Office中的一个问题。如果多个用户尝试从网络位置打开Excel文件,则第一个用户将锁定,其他用户无法保存,直到该用户保存为止。