我有一个关于@Transactional 注释如何单独管理代码和事务执行的问题。给定正确设置的 Spring 应用程序和以下代码:
@Transactional
public void withdraw(int amount) {
if(isEnoughFunds(amount)) {
decreaseFunds(amount);
}
}
是否有可能出现如下场景:
- 资金 == 100;金额 == 100
- 线程A进入withdraw/事务A开始
- 线程 A 执行 isEnoughFunds,结果为真
- 线程B进入withdraw/事务B开始
- 线程 B 执行 isEnoughFunds 计算结果为真
- 线程A执行decreaseFunds/线程A锁定数据库记录
- 线程B等待线程A提交事务并释放写锁
- 线程A退出撤回/事务A提交
- 线程B执行decreaseFunds/线程B锁定db记录
- 线程B退出撤回/事务B提交
- 资金 == -100
如果这是可能的,您将如何防止这种情况发生?
最佳答案
是的,这是可能的,具体取决于隔离级别。为了防止它,您可以在调用 ifEnoughFunds() 之前显式地从数据库获取读锁。锁将在事务结束时释放。在这种情况下,线程 B 将始终等待线程 A 的事务提交后再检查。
关于java - 使用@Transactional 保证线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12604476/