[P1/高] DatabaseService 迁移缺少事务包裹,部分失败导致 schema 不一致 #33

Open
opened 2026-07-21 21:55:59 +08:00 by thzxx · 0 comments
Owner

问题类型

缺陷 / 高 / 后端服务

文件位置

electron/services/database.service.ts

问题描述

DatabaseService.initialize 执行 schema 迁移:

migrations.forEach(migration => {
  db.exec(migration.sql);
  db.prepare('INSERT INTO schema_migrations ...').run(...);
});

每个 migration 单独执行,未包裹在事务中。若 migration SQL 部分失败(如 ALTER TABLE 成功,CREATE INDEX 失败):

  1. 数据库已部分变更
  2. schema_migrations 记录未写入
  3. 下次启动会重试该 migration,但 ALTER TABLE 已执行会失败
  4. 应用永久无法启动

影响

  • 升级失败后无法恢复
  • 数据库损坏

建议修复

migrations.forEach(migration => {
  const txn = db.transaction(() => {
    db.exec(migration.sql);
    db.prepare('INSERT INTO schema_migrations ...').run(...);
  });
  txn(); // 原子执行
});

// 整个迁移批次也包裹在外层事务中
const runAllMigrations = db.transaction(() => {
  migrations.forEach(m => runMigration(m));
});
runAllMigrations();

better-sqlite3 的事务是同步原子的,保证一致性。

## 问题类型 缺陷 / 高 / 后端服务 ## 文件位置 `electron/services/database.service.ts` ## 问题描述 DatabaseService.initialize 执行 schema 迁移: ```ts migrations.forEach(migration => { db.exec(migration.sql); db.prepare('INSERT INTO schema_migrations ...').run(...); }); ``` 每个 migration 单独执行,未包裹在事务中。若 migration SQL 部分失败(如 ALTER TABLE 成功,CREATE INDEX 失败): 1. 数据库已部分变更 2. schema_migrations 记录未写入 3. 下次启动会重试该 migration,但 ALTER TABLE 已执行会失败 4. 应用永久无法启动 ## 影响 - 升级失败后无法恢复 - 数据库损坏 ## 建议修复 ```ts migrations.forEach(migration => { const txn = db.transaction(() => { db.exec(migration.sql); db.prepare('INSERT INTO schema_migrations ...').run(...); }); txn(); // 原子执行 }); // 整个迁移批次也包裹在外层事务中 const runAllMigrations = db.transaction(() => { migrations.forEach(m => runMigration(m)); }); runAllMigrations(); ``` better-sqlite3 的事务是同步原子的,保证一致性。
thzxx added the ??????? labels 2026-07-21 21:55:59 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MetonaTeam/metona-ai-desktop#33