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

Flutter + MySQL:连续执行多查询失效问题(1条插入+2条更新)

问题分析与解决方案

核心问题:异步操作的执行顺序混乱

你遇到的问题根源在于三个数据库函数是异步执行的,但你在按钮点击事件里直接连续调用,没有等待前一个操作完成。这会导致:

  • updateDbActive1可能在insertScore还没把新记录写入数据库时就执行,所以当你把它改成设为0时,最新的那条记录还不存在,自然被遗漏;
  • updateDbActive2可能在前面的插入、更新操作都未完成时就运行,此时数据库里的数据还没更新,所以看起来完全没效果。

第一步:修复异步调用顺序

首先要确保三个操作按顺序执行,给按钮的onPressed添加async修饰符,并用await等待每个异步操作完成:

ElevatedButton(
  onPressed: () async { // 添加async
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();
      id = nameController.text;
      date = dateController.text;
      course = courseController.text;
      score = scoreController.text;
      
      setState(() {
        nameController.text = "";
        dateController.text = "";
        courseController.text = "";
        scoreController.text = "";
      });

      // 用await确保操作按顺序执行
      await database.insertScore(id, date, course, score);
      await database.updateDbActive1(id);
      await database.updateDbActive2(id);

      shouldDisplay = !shouldDisplay;
      if (shouldDisplay) {
        showAlertDialog(...);
      }
    }
  },
  // 其他属性...
)

第二步:优化数据库操作(更可靠的方案)

现在的代码每个操作都单独打开/关闭数据库连接,不仅效率低,还可能出现“部分操作成功、部分失败”的不一致状态。建议将三个操作合并到同一个数据库事务中,保证原子性(要么全部成功,要么全部回滚),同时减少连接开销:

// 替换原来的三个单独函数,写一个统一的提交函数
Future<void> submitScore(String id, String date, String course, String score) async {
  final conn = await connect();
  try {
    // 开启事务
    await conn.transaction((tx) async {
      // 1. 插入新分数
      await tx.query(
        "insert into Score (Bandit_ID, Bane, dato, Scores) values (?, ?, ?, ?)",
        [id, course, date, score]
      );
      // 2. 将该玩家所有分数设为非活跃(IkkeAktiv=1)
      await tx.query(
        "UPDATE Score SET IkkeAktiv = 1 WHERE Bandit_ID = ?",
        [id]
      );
      // 3. 将前10高分设为活跃(IkkeAktiv=0)
      await tx.query(
        "UPDATE Score SET IkkeAktiv = 0 WHERE Bandit_ID = ? ORDER BY Scores DESC LIMIT 10",
        [id]
      );
    });
  } catch (e) {
    // 捕获错误,比如打印日志或提示用户
    print("提交分数失败: $e");
    rethrow; // 可以让上层处理错误
  } finally {
    await conn.close(); // 确保数据库连接被关闭
  }
}

然后在按钮点击事件里只需要调用这个函数:

await database.submitScore(id, date, course, score);

额外注意事项

  1. 字段类型检查:确保Scores字段是数值类型(INT/DECIMAL),如果是字符串类型,排序会出错(比如"100"会比"99"小);
  2. 字段名一致性:你需求里的NotActive对应代码里的IkkeAktiv,确认数据库字段名拼写正确;
  3. 错误处理:建议在调用数据库操作时添加错误捕获,避免程序崩溃,同时给用户友好提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:52:27