我正在尝试在SQLServer上设置JPA乐观锁。为此,我使用TIMESTAMP
列(SQLServer TIMESTAMP
是一个递增的数字,不保留日期或时间)。
作为一个自动递增的数字,在我的Java实体上我需要将insertable / updatable设置为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首先执行SELECT
以检查记录是否已更改(1),然后更新(2)。如果记录被更改,则会抛出异常:
org.hibernate.StaleObjectStateException:行被另一个事务更新或删除
所以它工作正常,但我期待UPDATE
考虑版本(3)。实际上,如果将sql类型从TIMESTAMP
更改为NUMBER
并删除insertable / updateble,它将按预期工作。
如果UPDATE
不考虑版本(... AND tsrowversion=?
),如何保证乐观锁定?我怎样才能达到预期的行为?
答案 0 :(得分:0)
Hibernate检查内存实体的版本是否与持久版本相同。实体的id不会改变,除了Hibernate只保留一个实体版本,因此不需要在版本列上“过滤”。 也许这JPA and optimistic locking modes可以提供帮助