【问题标题】:using @Transactional for thread safety使用@Transactional 确保线程安全
【发布时间】:2012-09-26 14:51:08
【问题描述】:

我有一个关于 @Transactional 注释如何单独管理代码和事务执行的问题。给定正确设置的 Spring 应用程序和以下代码:

@Transactional
public void withdraw(int amount) {
    if(isEnoughFunds(amount)) {
        decreaseFunds(amount);
    }
}

会不会出现以下情况:

  • 资金 == 100;金额 == 100
  • 线程 A 进入提现/事务 A 开始
  • 线程 A 执行 isEnoughFunds,结果为真
  • 线程 B 进入提现/事务 B 开始
  • 线程 B 执行 isEnoughFunds,结果为真
  • 线程 A 执行 reductionFunds / 线程 A 锁定 db 记录
  • 线程 B 等待线程 A 提交事务并释放写锁
  • 线程 A 退出撤销/事务 A 提交
  • 线程 B 执行 reductionFunds / 线程 B 锁定数据库记录
  • 线程 B 退出退出/事务 B 提交
  • 资金 == -100

如果可能的话,你会如何防止这种情况发生?

【问题讨论】:

  • 注释只是说将其包装在事务中。数据库隔离级别决定了发生多少交错。

标签: java spring isolation-level transaction-isolation


【解决方案1】:

是的,有可能,具体取决于隔离级别。为了防止这种情况,您可以在调用 ifEnoughFunds() 之前从数据库中显式获取读锁。锁将在事务结束时释放。在这种情况下,线程 B 将始终等待线程 A 的事务提交后再进行检查。

【讨论】:

  • 你能用代码示例进一步解释一下如何在 spring 和 hibernate 中执行此操作吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多