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

打开IDBObjectStore触发DOMException:事务已完成问题求助

解决IndexedDB事务完成后无法获取ObjectStore的DOMException错误

错误原因分析

错误提示Failed to execute 'objectStore' on 'IDBTransaction': The transaction has finished的核心问题是:你在事务已经结束的时机去调用objectStore()方法。

IndexedDB的事务有明确的生命周期:当onComplete事件触发时,事务已经提交并释放了所有关联资源,此时再尝试访问事务内的ObjectStore会被拒绝。你的代码错误地套用了处理db.Request的逻辑——Request的onSuccess是请求完成、结果可用的时机,但Transaction的onComplete是事务结束的信号,不是获取资源的节点。

修正后的代码

调整completeTransaction函数的逻辑,在事务活跃时立即获取ObjectStore,再通过事务的事件确认状态:

Future<db.ObjectStore> completeTransaction(
  final db.Transaction transaction,
  final String objectStoreName,
) {
  final Completer<db.ObjectStore> completer = Completer<db.ObjectStore>.sync();
  
  // 事务创建后立即获取ObjectStore(此时事务处于活跃状态,合法)
  final db.ObjectStore objectStore = transaction.objectStore(objectStoreName);

  // 监听事务错误,将错误传递给completer
  transaction.onError.listen(completer.completeError);
  
  // 事务完成时,返回已获取的ObjectStore
  transaction.onComplete.listen((_) {
    completer.complete(objectStore);
  });

  return completer.future;
}

关键逻辑说明

  1. 时机调整:在事务刚创建(database.transactionStore返回的是活跃事务)时,直接调用transaction.objectStore()获取ObjectStore,这是符合IndexedDB规范的操作时机。
  2. 事件绑定:通过onError监听事务执行中的错误,通过onComplete确认事务顺利完成,最终将已准备好的ObjectStore返回给调用方。
  3. 区别Request与Transaction:原_completeRequest函数处理的是单次请求,onSuccess是请求结果就绪的信号;而Transaction代表的是一组操作的集合,onComplete是整个操作集合结束的通知,两者的生命周期逻辑完全不同,不能直接复用代码结构。

调用方式说明

你的原有调用方式不需要修改,因为database.transactionStore返回的是刚创建的活跃事务,传递给修正后的函数可以直接获取到合法的ObjectStore:

void main() async {
  ...

    await completeTransaction(
      database.transactionStore(objectStoreName, "readwrite"),
      objectStoreName,
    );

  ...
}

内容的提问来源于stack exchange,提问作者gitman-2021

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:50:26