【问题标题】:Hibernate @Version - hit databaseHibernate @Version - 命中数据库
【发布时间】:2017-08-22 13:12:56
【问题描述】:

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

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

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

【问题讨论】:

  • Hibernate 会为你做这件事。

标签: java hibernate


【解决方案1】:

不,你不要手动弄乱版本,而是让 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 并抛出 @ 987654326@.

【讨论】:

    猜你喜欢
    • 2017-04-01
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2014-11-12
    • 2014-05-24
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多