繁体   English   中英

应用程序级锁定和休眠乐观锁定

[英]Application-level locking and hibernate optimistic locking

我正在使用像MariaDB这样的休眠乐观锁定

@Version
@Column(columnDefinition="TIMESTAMP(3) DEFAULT '2016-01-01'")
private Timestamp timestamp;

最近,我有一个StaleStateException ,作为一个快速的技巧,我试图通过锁定应用程序来对抗它。 这导致以下顺序(第二列是线程号;每个线程都有自己的连接):

A 1 createSession
B 2 createSession
C 1 read some irrelevant entity
D 2 read some irrelevant entity
E 1 try to obtain lock
F 2 try to obtain lock
G 1 LOCK GRANTED
H 1 READ THE ENTITY, timestamp=2016-09-28 14:52:32.076
I 1 do some other stuff
J 1 WRITE THE ENTITY, new timestamp=2016-09-28 14:52:32.076
K 1 COMMIT
L 1 release lock
M 2 LOCK GRANTED
N 1 READ THE ENTITY, timestamp=2016-09-28 14:52:32.076
O 2 do some other stuff
P 2 WRITE THE ENTITY, StaleStateException

问题显然出在第N行,第二个线程看到了旧的时间戳。 我没有在任何地方指定隔离级别,Mysql的默认级别应该是REPEATABLE READ ,但是AFAIK没有级别,即使是SNAPSHOT或SERIALIZABLE也应该使第二个线程看到旧值,应该吗?

我看到应用程序级锁定是一个坏主意,我只是想了解发生了什么,然后再切换到重试或DB锁定。

一个可能的原因是我使用JodaTime Instant进行版本控制 版本 已损坏

您尚未说明的是事务的开始和结束位置。

如果每个会话在步骤A和B启动事务,那么确实可以,“可序列化”将意味着会话2仅会看到它提交的旧时间戳记单位并开始新事务。

如果会话2使用“读取已提交”,则它将在会话1提交后看到新值。

在此示例中,JPA完全按照您的要求进行操作,并使用“版本”字段来避免进行隐式更新。 如果您不在乎,并且仍要进行更新,请不要使用Version ...?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM