休眠-交易:两个帐户之间的一致性

时间:2018-10-12 06:00:26

标签: java spring hibernate

如何在Hibernate中保持事务之间的一致性,例如,我有这种情况-

我有两项交易,T1T2, 两者同时在同一个帐户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

该如何解决?

  • A =帐户,表示元组,即RDBMS表中的行。在这里,它代表一个由帐号唯一标识的银行帐户。

1 个答案:

答案 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来实现此目的。