使用@Transactional来保证线程安全

use*_*598 7 java spring transaction-isolation isolation-level

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

@Transactional
public void withdraw(int amount) {
    if(isEnoughFunds(amount)) {
        decreaseFunds(amount);
    }
}
Run Code Online (Sandbox Code Playgroud)

是否可能发生以下情况:

  • 资金== 100; 金额== 100
  • 线程A进入撤销/交易A开始
  • 线程A执行isEnoughFunds,其计算结果为true
  • 线程B进入撤销/交易B开始
  • 线程B执行isEnoughFunds,其计算结果为true
  • 线程A执行decreaseFunds/thread A锁定db记录
  • 线程B等待线程A提交事务并释放写锁定
  • 线程A退出撤销/事务A提交
  • 线程B执行decreaseFunds/thread B锁定db记录
  • 线程B退出撤销/事务B提交
  • 资金== -100

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

Ass*_*lov 4

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

  • 您能用代码示例进一步解释如何在 spring 和 hibernate 中执行此操作吗?谢谢你! (4认同)