JPA乐观锁与SQLServer TIMESTAMP

时间:2017-07-17 12:43:03

标签: jpa timestamp locking optimistic

我正在尝试在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=?),如何保证乐观锁定?我怎样才能达到预期的行为?

1 个答案:

答案 0 :(得分:0)

Hibernate检查内存实体的版本是否与持久版本相同。实体的id不会改变,除了Hibernate只保留一个实体版本,因此不需要在版本列上“过滤”。 也许这JPA and optimistic locking modes可以提供帮助