1

我正在尝试在 SQLServer 上设置 JPA 乐观锁。为此,我使用了一个TIMESTAMP列(SQLServerTIMESTAMP是一个递增的数字,不保留日期或时间)。

作为一个自动递增的数字,在我的 Java 实体上,我需要将可插入/可更新设置为,false否则我会得到一个异常:

com.microsoft.sqlserver.jdbc.SQLServerException:无法更新时间戳列

这是我的 Java 实体映射:

@Version
@Column(name = "TSROWVERSION", insertable = false, updatable = false)
private byte[] version;

当我更新一条记录时,这个 SQL 被执行:

(1) *SELECT ... FROM cmd_e_entities WHERE uidentity=?*

(2) *UPDATE cmd_e_entities SET... WHERE uidentity=?*

但我期待得到类似的东西:

(3) *UPDATE cmd_e_entities SET... WHERE uidentity=? AND tsrowversion=?*

Hibernate 首先执行 aSELECT以检查记录是否已更改 (1),然后更新 (2)。如果记录被更改,则会引发异常:

org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除

所以它工作正常,但我期待UPDATE考虑到版本(3)。实际上,如果将 sql 类型从TIMESTAMPto更改为NUMBER并删除可插入/可更新,它将按预期工作。

如果UPDATE不考虑版本(... AND tsrowversion=?)如何保证乐观锁?我怎样才能得到我的预期行为?

4

1 回答 1

0

Hibernate 检查内存中实体的版本是否与持久化实体的版本相同。实体的 id 不会改变,除了 Hibernate 只保留一个实体的版本,因此不需要在版本列上“过滤”。也许这种JPA 和乐观锁定模式会有所帮助

于 2017-07-17T13:09:35.290 回答