[P1/高] SessionService saveMessage 更新 message_count 非原子性,并发下计数错误 #34

Closed
opened 2026-07-21 21:56:00 +08:00 by thzxx · 1 comment
Owner

问题类型

缺陷 / 高 / 后端服务

文件位置

electron/services/session.service.ts

问题描述

saveMessage 实现:

saveMessage(msg) {
  // 1. 插入消息
  db.prepare('INSERT INTO messages ...').run(msg);

  // 2. 读取当前 count
  const count = db.prepare('SELECT message_count FROM sessions WHERE id = ?').get(msg.sessionId);

  // 3. 更新 count
  db.prepare('UPDATE sessions SET message_count = ? WHERE id = ?').run(count + 1, msg.sessionId);
}

非原子操作,并发下:

  • 两个 saveMessage 同时读取 count=10
  • 各自 +1,更新为 11
  • 实际应是 12

影响

  • message_count 不准
  • UI 显示错误

建议修复

方案 A(推荐):使用 SQL 表达式

UPDATE sessions SET message_count = message_count + 1 WHERE id = ?;

方案 B:包裹事务

const txn = db.transaction(() => {
  db.prepare('INSERT INTO messages ...').run(msg);
  db.prepare('UPDATE sessions SET message_count = message_count + 1 WHERE id = ?').run(msg.sessionId);
});
txn();

方案 A 更简洁。

## 问题类型 缺陷 / 高 / 后端服务 ## 文件位置 `electron/services/session.service.ts` ## 问题描述 saveMessage 实现: ```ts saveMessage(msg) { // 1. 插入消息 db.prepare('INSERT INTO messages ...').run(msg); // 2. 读取当前 count const count = db.prepare('SELECT message_count FROM sessions WHERE id = ?').get(msg.sessionId); // 3. 更新 count db.prepare('UPDATE sessions SET message_count = ? WHERE id = ?').run(count + 1, msg.sessionId); } ``` 非原子操作,并发下: - 两个 saveMessage 同时读取 count=10 - 各自 +1,更新为 11 - 实际应是 12 ## 影响 - message_count 不准 - UI 显示错误 ## 建议修复 方案 A(推荐):使用 SQL 表达式 ```sql UPDATE sessions SET message_count = message_count + 1 WHERE id = ?; ``` 方案 B:包裹事务 ```ts const txn = db.transaction(() => { db.prepare('INSERT INTO messages ...').run(msg); db.prepare('UPDATE sessions SET message_count = message_count + 1 WHERE id = ?').run(msg.sessionId); }); txn(); ``` 方案 A 更简洁。
thzxx added the ??????? labels 2026-07-21 21:56:00 +08:00
Author
Owner

修复说明

文件: electron/services/session.service.ts

修复: saveMessage 已用 message_count = message_count + 1(原子 SQL 表达式)。进一步包裹事务保证 INSERT messages 和 UPDATE sessions 原子执行,避免部分失败导致消息已插入但计数未更新。

验证: tsc --noEmit 类型检查通过。

## 修复说明 **文件**: `electron/services/session.service.ts` **修复**: saveMessage 已用 `message_count = message_count + 1`(原子 SQL 表达式)。进一步包裹事务保证 INSERT messages 和 UPDATE sessions 原子执行,避免部分失败导致消息已插入但计数未更新。 **验证**: `tsc --noEmit` 类型检查通过。
thzxx closed this issue 2026-07-22 09:43:12 +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#34