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

Apache Ignite持续执行SELECT与UPDATE操作时出现死锁错误

Apache Ignite 3.0.0并发SELECT/UPDATE死锁问题排查与优化方案

问题背景

使用Apache Ignite 3.0.0版本,创建表结构如下:

CREATE TABLE INSTANT_CDR (
  MSISDN VARCHAR PRIMARY KEY,
  RECHARGE_AMOUNT DOUBLE,
  VOICE_AMOUNT DOUBLE,
  LAST_NAME VARCHAR,
  BALANCE DOUBLE
);

通过JDBC Java程序对该表执行以下操作:

  • 查询语句:
SELECT * FROM INSTANT_CDR WHERE MSISDN='123456789'
  • 更新语句:
UPDATE INSTANT_CDR SET RECHARGE_AMOUNT=RECHARGE_AMOUNT+1, VOICE_AMOUNT=VOICE_AMOUNT+1 WHERE MSISDN='123456789'

持续执行插入和更新操作时,Ignite端抛出如下错误:

Caused by: org.apache.ignite.internal.tx.LockException: IGN-TX-4 TraceId:b5f06ecc-1378-4315-96d9-e25d9ff70e6f Failed to acquire a lock due to a possible deadlock [locker=0195176a-f0ce-000b-e5f1-efe300000001, holder=0195176a-f0ce-000b-e5f1-efe300000001]
at org.apache.ignite.internal.tx.impl.HeapLockManager.lockException(HeapLockManager.java:424)
at org.apache.ignite.internal.tx.impl.HeapLockManager$LockState.isWaiterReadyToNotify(HeapLockManager.java:931)
at org.apache.ignite.internal.tx.impl.HeapLockManager$LockState.tryAcquire(HeapLockManager.java:851)
at org.apache.ignite.internal.tx.impl.HeapLockManager.acquire(HeapLockManager.java:216)
20 more

Ignite并发SELECT/UPDATE的处理机制

Ignite 3.0.0采用乐观锁+悲观锁结合的事务模型,默认规则如下:

  • 事务内的SELECT语句会获取共享锁(S锁),允许其他事务读取同一行,但会阻止排他锁(X锁)的获取;
  • UPDATE语句会尝试将共享锁升级为排他锁(X锁),或直接获取排他锁,此时会阻止其他事务的读写操作。

日志中出现同一事务ID既是锁请求者又是持有者的情况,并非真死锁,通常是事务上下文管理不当、锁超时配置过短导致的异常告警。

死锁问题解决与并发优化方案

1. 规范事务边界

  • 确保SELECT与UPDATE在同一事务内执行,避免跨事务的锁竞争。分开的事务会导致SELECT持有的S锁与UPDATE的X锁相互阻塞;
  • 减少事务内重复执行相同SELECT的次数,缩短锁持有时间。

2. 调整锁与事务超时配置

在Ignite配置文件(如ignite-config.yaml)中修改以下参数,避免因超时触发假死锁:

transaction:
  defaultTimeout: 60000 # 默认事务超时设为60秒
lock:
  waitTimeout: 10000 # 锁等待超时设为10秒

3. 优化SQL与锁粒度

  • 直接使用原子UPDATE语句完成操作(当前更新语句已满足原子性),避免先SELECT再UPDATE的冗余流程,减少锁持有时间;
  • 若必须执行前置查询,使用SELECT ... FOR UPDATE显式获取排他锁,避免后续锁升级冲突:
SELECT * FROM INSTANT_CDR WHERE MSISDN='123456789' FOR UPDATE

4. 启用乐观事务模式

乐观事务通过版本号而非锁控制并发,适合高并发读写场景。在JDBC代码中启用:

Connection conn = DriverManager.getConnection(jdbcUrl);
conn.setAutoCommit(false);
// 乐观事务依赖读已提交隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
// 执行查询与更新操作
conn.commit();

5. 调整锁管理器配置

启用公平锁避免线程饥饿,优化高并发场景下的锁分配:

lock:
  fairLock: true

内容的提问来源于stack exchange,提问作者Arjun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:38:11