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

iOS发布模式下触发sqflite错误:cannot commit - no transaction is active

iOS发布模式下sqflite报错:cannot commit - no transaction is active 排查与解决

错误信息

flutter: error DatabaseException(Error Domain=SqfliteDarwinDatabase Code=1 "cannot commit - no transaction is active" UserInfo={NSLocalizedDescription=cannot commit - no transaction is active}) sql 'COMMIT' args [] during open, closing...
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DatabaseException(Error Domain=SqfliteDarwinDatabase Code=1 "cannot commit - no transaction is active" UserInfo={NSLocalizedDescription=cannot commit - no transaction is active}) sql 'COMMIT' args []

问题场景

  • 仅在iOS发布模式下启动应用时触发该错误
  • 应用启动后黑屏,但会正常请求相机权限

核心代码实现

获取数据库实例 getDBInstance

Future<Database> getDBInstance({BuildContext? context}) async {
  debugPrint('getting db instance');
  if (database == null) {
    debugPrint('db is null');
    Database db;
    if (Platform.isWindows) {
      sqfliteFfiInit();
      var databaseFactory = databaseFactoryFfi;
      db = await databaseFactory.openDatabase("cashway.db",
          options: OpenDatabaseOptions(
              version: 1, onCreate: onCreate, onUpgrade: onUpgrade));
    } else {
      String databasesPath = await getDatabasesPath();
      String dbPath = join(databasesPath, 'cashway.db');
      //the last printed output
      debugPrint('opening db');
      db = await openDatabase(dbPath,
          version: 1, onCreate: onCreate, onUpgrade: onUpgrade);
    }
    database = db;
    return db;
  } else {
    Database db = database!;
    return db;
  }
}

数据库创建回调 onCreate

void onCreate(Database database, int version) async {
  debugPrint('on create');
  for (MigrationCallback callback in migrations) {
    debugPrint('doin migration');
    await callback(database);
  }
  resetDatabase();
}

应用入口 main

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await getDBInstance();

  AppProvider appProvider = await AppProvider.getInstance();

  runApp(MultiProvider(
      providers: [ChangeNotifierProvider(create: (_) => appProvider)],
      child: const App()));
}

数据库重置方法 resetDatabase

Future<void> resetDatabase(database) async {
  debugPrint('resetting');
  database.delete("payments", where: "id>0");
  database.delete("accounts", where: "id>0");
  database.delete("categories", where: "id>0");
  debugPrint('removed all entries');

  await database.insert("accounts", {
    "name": "Наличные",
    "icon": Icons.wallet.codePoint,
    "color": Colors.teal.value,
    "isDefault": 1
  });
}

排查与解决思路

1. 核心问题定位

错误提示cannot commit - no transaction is active,本质是代码中存在未等待异步操作完成就触发事务提交的情况:

  • resetDatabase中的3个delete操作未加await,导致这些异步操作在后台执行时,sqflite的隐式事务逻辑出现异常
  • onCreate调用resetDatabase时也未加await,导致数据库创建流程提前结束,触发事务提交错误

2. 修复步骤

修复resetDatabase中的异步等待

给所有数据库操作添加await,确保操作顺序执行:

Future<void> resetDatabase(database) async {
  debugPrint('resetting');
  await database.delete("payments", where: "id>0");
  await database.delete("accounts", where: "id>0");
  await database.delete("categories", where: "id>0");
  debugPrint('removed all entries');

  await database.insert("accounts", {
    "name": "Наличные",
    "icon": Icons.wallet.codePoint,
    "color": Colors.teal.value,
    "isDefault": 1
  });
}

修复onCreate中的异步等待

确保resetDatabase执行完成后再结束创建流程:

void onCreate(Database database, int version) async {
  debugPrint('on create');
  for (MigrationCallback callback in migrations) {
    debugPrint('doin migration');
    await callback(database);
  }
  await resetDatabase(database);
}

3. 额外验证点

  • 检查migrations中的所有迁移操作,确保异步数据库操作都添加了await
  • 用flutter run --release命令重新验证iOS发布模式下的运行情况
  • 确认数据库单例的访问逻辑,避免多线程同时触发数据库操作(sqflite为单线程设计,异步操作需保证顺序)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 11:00:14