如何在Hibernate中保持事务之间的一致性,例如,我有这种情况-
我有两项交易,T1
和T2
,
两者同时在同一个帐户A
(初始值= 500
)上进行操作,
T1
要加200
,而T2
要从100
减去A
。
如果交易是这样-
1. T1 reads value of A as 500, T2 reads value of A as 500.
2. T1 does A = 500 + 200.
3. T2 does A = 500 -100.
4. T2 commits value of A as 400.
5. T1 commits Value of A as 700.
A
的最终值为700
,不正确。 A
的正确值应为600
。
该如何解决?
答案 0 :(得分:1)
您可以选择两种策略。
第一个是乐观锁定。它使您能够检测到这种情况并通过使第二笔交易失败来解决它们。这意味着
T1提交A的值为700。
产生javax.persistence.OptimisticLockException
。要实现此策略,您应该在A
实体中创建表示当前元组版本的特殊列,并用javax.persistence.Version
对其进行注释。每次提交后,Jpa提供程序都会自动增加版本列,并在每次提交时检查其值,如下所示:
1. T1 reads value of A (v1) as 500, T2 reads value of A (v1) as 500 .
2. T1 does A = 500 + 200.
3. T2 does A = 500 -100.
4. T2 commits value of A as 400 - db and entity versions are the same
5. T1 commits Value of A (v1) as 700 - version mismatch: db version is v2 and current version is v1 -> OptimisticLockException
第二种策略是悲观锁定(独占锁定):
它允许第一个事务(在您的示例中为T1)锁定Tuple,使其无法从其他事务读取/写入它,直到在commit \ rollback上释放锁定为止。您可以通过将javax.persistence.EntityManager#lock
作为第二个参数来调用javax.persistence.LockModeType#WRITE
来实现此目的。