You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot两事务更新同一行时事务挂起问题排查

问题:同一行数据跨独立事务更新时出现挂起的原因分析

我尝试通过编程方式管理两个独立事务来更新同一行数据,测试代码如下:

@Sql("classpath:sql/balance/account_with_balance_EE.sql")
@Test
void changeNoLock() {
    long balanceId = 10000L;
    DefaultTransactionDefinition firstTransactionDefinition = new DefaultTransactionDefinition();
    DefaultTransactionDefinition secondTransactionDefinition = new DefaultTransactionDefinition();
    firstTransactionDefinition.setName("firstTransaction");
    secondTransactionDefinition.setName("secondTransaction");
    firstTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    secondTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

    TransactionStatus firstTransactionStatus = txManager.getTransaction(firstTransactionDefinition);
    balanceService.change(balanceId, BigDecimal.ONE);

    TransactionStatus secondTransactionStatus = txManager.getTransaction(secondTransactionDefinition);
    balanceService.change(balanceId, BigDecimal.ONE);

    txManager.commit(firstTransactionStatus);
    txManager.commit(secondTransactionStatus);


    BalanceDto balanceDto = balanceService.find(balanceId);

    assertEquals(new BigDecimal("2.00"), balanceDto.getBalanceAmount());
}

balanceService#change方法使用默认的事务传播行为和隔离级别。运行该测试时出现挂起现象,仅当先提交第一个事务再启动第二个事务时才不会挂起,请问该现象的原因是什么?当前使用的技术栈为Java 17、Spring Boot 3以及PostgreSQL数据库。


原因分析

1. PostgreSQL的行级排他锁机制

PostgreSQL执行UPDATE语句时,会对目标数据行添加排他锁(Exclusive Lock),该锁会持续持有至事务提交或回滚。在你的测试中,第一个事务执行balanceService.change后,已对balanceId=10000的行加锁,且此时第一个事务未提交,锁处于未释放状态。

2. 独立事务的锁阻塞

你为两个事务设置了PROPAGATION_REQUIRES_NEW传播行为,这会创建两个独立的物理事务(对应不同的数据库连接)。当第二个事务尝试更新同一行时,PostgreSQL会检测到该行已被其他事务持有排他锁,因此第二个事务会进入等待状态,直到锁被释放。

但你的代码逻辑是先启动两个事务并执行更新,再依次提交,这导致第二个事务等待第一个事务释放锁,而第一个事务需等待第二个事务执行完成才提交,形成循环等待,最终引发挂起。

3. 先提交第一个事务的可行原因

若调整逻辑为先提交第一个事务,再启动第二个事务,第一个事务提交后会立即释放排他锁,第二个事务执行UPDATE时可正常获取锁,不会出现阻塞,因此不会挂起。


内容的提问来源于stack exchange,提问作者dev-rifaii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:52:55