java - 使用@Transactional 保证线程安全

标签 java spring isolation-level transaction-isolation

我有一个关于@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/

相关文章:

angular - 在Docker中部署Spring Boot和Angular应用时出现CORS错误

java - CompletableFuture 能否用于创建非阻塞 I/O 调用?

mysql - InnoDB SELECT ... FOR UPDATE 语句锁定表中的所有行

java - Selenium WebDriver java 测试中的 StaleElementReferenceException

java - Controller 在进行 spring/hibernate 调用时会阻塞吗?

java - AspectJ - 从建议中访问类变量/方法值?

java - 用 Java 实现 RTSP 媒体服务器

java - Spring Web应用程序初始化器

sql-server - SQL Server 2012 插入 block 读取