我使用@version注释来实现乐观阻塞但是当我在保存/更新操作之前保存对象时检查数据库中哪个版本有,然后将其分配给我的对象并保存,我是对的吗?
- 创建新对象
- 点击数据库并为其分配db版本
- 保存到数据库
醇>
http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html
答案 0 :(得分:2)
不,你不要手动搞乱版本,但让Hibernate处理它。
通常情况如下:
update ... set version = :newVersion ... where version := expectedVersion
之类的更新查询(expectedVersion
是在步骤1中读取的版本值,newVersion
是expectedVersion + 1
并检查更新是否发生。请注意,您是直接使用更新查询,因为Hibernate不会/不会改变您的查询,所以不会发生版本检查。
如果您按照自己在问题中的建议行事,即从db中读取版本,将其设置为对象然后写入,会发生什么?
如果是新对象,您将无法获得任何版本,因此需要使用一些默认值(在这种情况下,您可以让Hibernate也提供该默认值)。
如果你要更新一个对象,你基本上会绕过乐观锁定。为什么呢?
假设名为A和B的两个线程/用户读取您的对象。最初它有版本0所以都看到该版本。现在A更新对象,因此版本变为1.现在,如果B也想要更新对象(并注意它仍然看到与版本0关联的数据),您的建议将仅读取版本,将其设置为1和写。写入成功但您最终可能会丢失更新,因为内存中的数据不会反映A所做的任何更新。
如果我们让Hibernate处理该版本,另一方面B的更新将导致... where version = 0
,但由于A的更新已经将版本更改为1,所以不会更新任何内容,因此Hibernate看到行数为0并抛出OptimisticLockException
。