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

GridDB多事务执行时报10905 TXN_WAIT_FOR_TRANSACTION_END错误的咨询

解决GridDB 10905 TXN_WAIT_FOR_TRANSACTION_END错误的方案

错误原因分析

10905错误本质是同一容器上的并发事务因锁冲突进入等待状态,结合你的代码来看,核心问题有两个:

  • 共享了非线程安全的GridStore实例:GridDB的GridStore对象不支持多线程并发操作,多个线程共用同一个实例会引发事务管理混乱,加剧锁冲突。
  • 事务操作同一行数据:你的示例中所有事务都写入主键为1的行,触发行级锁的排他性,导致后续事务必须等待前一个事务释放锁。

具体解决方法

1. 保证线程独立使用GridStore实例

每个线程必须单独获取GridStore连接,避免多线程共享同一个实例。修改后的代码示例:

import com.toshiba.mwcloud.gs.Container;
import com.toshiba.mwcloud.gs.GridStore;
import com.toshiba.mwcloud.gs.GridStoreFactory;
import com.toshiba.mwcloud.gs.Row;
import com.toshiba.mwcloud.gs.GSException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class GridDBTransactionTest {
    public static void main(String[] args) {
        try {
            ExecutorService executorService = Executors.newFixedThreadPool(3);

            for (int i = 0; i < 3; i++) {
                final int threadId = i;
                executorService.submit(() -> {
                    GridStore store = null;
                    try {
                        // 每个线程独立获取GridStore实例
                        store = GridStoreFactory.getInstance().getGridStore();
                        Container<Row> container = store.getContainer("SampleContainer");
                        
                        store.setAutoCommit(false);
                        // 写入不同行,避免同一行锁冲突
                        container.put(new Row(threadId + 1, "Sample Data " + threadId));
                        store.commit();
                    } catch (GSException e) {
                        if (store != null) {
                            try {
                                store.rollback();
                            } catch (GSException ex) {
                                ex.printStackTrace();
                            }
                        }
                        e.printStackTrace();
                    } finally {
                        if (store != null) {
                            try {
                                store.close();
                            } catch (GSException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }

            executorService.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. 优化事务操作粒度,避免锁冲突

  • 避免同一行的并发写:如果业务允许,尽量让不同事务操作不同行数据,利用GridDB的行级锁特性提升并发度。
  • 缩小事务范围:尽量缩短事务的执行时间,减少锁持有时长,降低冲突概率。

3. 调整GridDB事务参数

  • 设置事务超时时间:通过GridStore.setTransactionTimeout()设置事务等待超时,避免无限等待:
    store.setTransactionTimeout(5000); // 超时时间5秒
    
  • 调整事务隔离级别:GridDB支持READ_COMMITTED和REPEATABLE_READ,如果业务允许,使用READ_COMMITTED可以减少锁持有时间:
    store.setTransactionIsolation(TransactionIsolation.READ_COMMITTED);
    

4. 安全管理并发事务的最佳实践

  • 避免长事务:长事务会持续占用锁资源,大幅提升冲突概率,尽量将大事务拆分为多个小事务。
  • 使用乐观锁(可选):如果业务场景允许,通过版本字段实现乐观锁,避免悲观锁的等待:
    1. 在容器中添加版本字段(如int version)
    2. 读取数据时获取版本号,更新时校验版本号是否一致,不一致则重试

总结

  1. 必须保证每个线程使用独立的GridStore实例,这是解决线程安全问题的基础。
  2. 优化事务操作的行范围,减少同一行的并发写操作,是降低锁冲突的核心。
  3. 通过调整事务超时、隔离级别等参数,进一步优化并发性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:53