不,你不要手动弄乱版本,而是让 Hibernate 处理它。
通常是这样的:
- 您从数据库加载实体,包括其版本
- 您更改了该实体中的一些数据
- 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 并抛出 @ 987654326@.