Hibernate @Version - 命中数据库

时间:2017-08-22 13:12:57

标签: java hibernate

我使用@version注释来实现乐观阻塞但是当我在保存/更新操作之前保存对象时检查数据库中哪个版本有,然后将其分配给我的对象并保存,我是对的吗?

  
      
  1. 创建新对象
  2.   
  3. 点击数据库并为其分配db版本
  4.   
  5. 保存到数据库
  6.   

http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html

1 个答案:

答案 0 :(得分:2)

不,你不要手动搞乱版本,但让Hibernate处理它。

通常情况如下:

  • 您从数据库加载实体,包括其版本
  • 您更改该实体中的某些数据
  • Hibernate最终刷新更改并发出包含update ... set version = :newVersion ... where version := expectedVersion之类的更新查询(expectedVersion是在步骤1中读取的版本值,newVersionexpectedVersion + 1并检查更新是否发生。

请注意,您是直接使用更新查询,因为Hibernate不会/不会改变您的查询,所以不会发生版本检查。

如果您按照自己在问题中的建议行事,即从db中读取版本,将其设置为对象然后写入,会发生什么?

如果是新对象,您将无法获得任何版本,因此需要使用一些默认值(在这种情况下,您可以让Hibernate也提供该默认值)。

如果你要更新一个对象,你基本上会绕过乐观锁定。为什么呢?

假设名为A和B的两个线程/用户读取您的对象。最初它有版本0所以都看到该版本。现在A更新对象,因此版本变为1.现在,如果B也想要更新对象(并注意它仍然看到与版本0关联的数据),您的建议将仅读取版本,将其设置为1和写。写入成功但您最终可能会丢失更新,因为内存中的数据不会反映A所做的任何更新。

如果我们让Hibernate处理该版本,另一方面B的更新将导致... where version = 0,但由于A的更新已经将版本更改为1,所以不会更新任何内容,因此Hibernate看到行数为0并抛出OptimisticLockException