【问题标题】:Block application thread to read DB while another transaction is in process在另一个事务正在进行时阻止应用程序线程读取数据库
【发布时间】:2019-02-12 09:02:17
【问题描述】:

我正在多租户(单独的物理盒子)上运行多线程应用程序。如果在同一时间 t1 有两个交易 Tr1 和 Tr2 出现在不同的租户上,那么功能之一是在这种情况下更新客户的余额,那么它不会正确更新余额。我无法将其作为多租户同步,因此边界是单台机器上的 JVM。

技术:Spring、hibernate 和 MS SQL。

我想阻止应用程序线程 tr2(租户 1 上的线程)读取数据(当然对于同一客户)并在 tr1(另一个租户上的线程)线程已经在处理数据时处理它。

【问题讨论】:

  • “它没有正确更新余额”是什么意思?您是否有版本列并因此启用了乐观锁定?
  • 不,我的表中没有版本列。余额未更新意味着,如果起始余额为 7 美元,交易 tr1 为 2 美元,tr2 为 3 美元,那么在两次更新后,余额有时为 5 美元或 4 美元,其中预期的期末余额为 2 美元。

标签: hibernate transactions spring-data-jpa


【解决方案1】:

您可以使用以下两种方法之一:

乐观锁定:JPA 不会创建额外的锁,而是使用版本列来确保它正在更新的值与最初加载的值相同,如果不是这种情况则抛出异常。

您可以简单地通过添加版本属性来启用它,即带有@Version 注释的列。当然,您必须捕获生成的 OptimisticLockException 并采取相应措施(可能再试一次)。

悲观锁定:JPA 将在数据库行上创建一个锁,因此在 JPA 提交之前无法更改它。

the reference documentation of Spring Data JPA

这是related question about how to achieve that

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多