有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate事务:两个帐户之间的一致性

如何在Hibernate中保持事务之间的一致性,例如,我有这样的场景-

我有两笔交易,T1&T2, 两者同时在同一账户上运行A(初始值=500), T1想做200加法T2想从A减去100。 如果交易是这样发生的——

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) 个答案

  1. # 1 楼答案

    你可以选择两种策略

    第一个是乐观锁定。它允许您检测这种情况,并通过第二次事务失败来解决它们。这意味着

    T1 commits Value of A as 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)从另一个事务读取\写入元组,直到释放提交\回滚锁定。您可以通过调用javax.persistence.EntityManager#lock并将javax.persistence.LockModeType#WRITE作为第二个参数来实现这一点