招待承認のような複合操作はD1 batchでアトミックにする
プロジェクトへの招待→承認→メンバー追加のフローは、invitation更新とmember挿入の2クエリが必要になる。片方だけ成功すると「承認済みだがメンバーでない」という不整合が起きる。
Cloudflare D1の db.batch() を使えば、複数のprepared statementをトランザクション相当でまとめて実行できる。
const results = await db.batch([
db.prepare(
"UPDATE invitations SET status = 'accepted', accepted_by = ?1, accepted_at = ?2 WHERE id = ?3"
).bind(userId, now, invitationId),
db.prepare(
"INSERT INTO members (project_id, user_id, role) VALUES (?1, ?2, ?3)"
).bind(projectId, userId, role),
]);
ポイント:
- D1にはBEGIN/COMMITはないが、
batch()が同等の保証を提供する - 招待の重複チェック(既にpendingがあるか)はbatchの前にSELECTで行う
- 招待→承認→メンバー追加のような状態遷移を伴う複合操作は、batch対象の筆頭候補