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

MySQL多事件并行插入时的随机失败问题排查

问题原因与解决方案

核心原因

你遇到的问题是并发竞争导致的重复插入冲突,和自增主键无关,关键在于子查询的非原子性:

  • 当5个事件同时执行时,多个数据库会话会在同一时刻执行子查询,此时所有会话都能看到同一个未被插入到PublishRecord的ChapterKey(因为还没有任何会话完成插入操作)。
  • 第一个会话成功插入后,后续会话再插入同一个TierKey+ChapterKey组合时,会触发唯一约束冲突(大概率是PublishRecord表存在TierKey和ChapterKey的组合唯一约束,只是你没留意到),导致插入失败。
  • 手动执行时没有并发竞争,子查询能正确拿到未被占用的ChapterKey,所以不会冲突。

解决办法

1. 用INSERT ... SELECT加行锁避免重复选取(推荐)

把原SQL改成INSERT ... SELECT形式,并在子查询中添加FOR UPDATE SKIP LOCKED(MySQL 8.0+、PostgreSQL等主流数据库支持),这样在选取章节时会锁定该行,其他会话会直接跳过已锁定的行,避免重复选取:

INSERT INTO PublishRecord (TierKey, ProductId, PageKey, StoryKey, PublishDate, ChapterKey)
SELECT 
    'liesijznoo',
    'prod_oOcEiHmKEh04Ag',
    'lies5yw6p3',
    'liyy27t7t7',
    NOW(),
    cid
FROM (
    SELECT PublishingQueue.ChapterKey as cid 
    FROM PublishingQueue
    LEFT JOIN Chapters ON Chapters.ChapterKey = PublishingQueue.ChapterKey
    LEFT JOIN PublishRecord ON PublishRecord.ChapterKey = PublishingQueue.ChapterKey AND PublishRecord.TierKey = 'liesijznoo'
    WHERE Chapters.StoryKey = 'liyy27t7t7' AND PublishRecord.TierKey IS NULL
    ORDER BY Chapters.ChapterOrder ASC 
    LIMIT 1
    FOR UPDATE SKIP LOCKED
) as c00;

2. 悲观锁+事务兜底

如果你的数据库不支持SKIP LOCKED,可以把插入逻辑放在事务中,先锁定目标章节行,确保只有当前会话能操作:

START TRANSACTION;
-- 先锁定要选取的章节
SELECT PublishingQueue.ChapterKey as cid 
FROM PublishingQueue
LEFT JOIN Chapters ON Chapters.ChapterKey = PublishingQueue.ChapterKey
LEFT JOIN PublishRecord ON PublishRecord.ChapterKey = PublishingQueue.ChapterKey AND PublishRecord.TierKey = 'liesijznoo'
WHERE Chapters.StoryKey = 'liyy27t7t7' AND PublishRecord.TierKey IS NULL
ORDER BY Chapters.ChapterOrder ASC 
LIMIT 1
FOR UPDATE;

-- 执行插入
INSERT INTO PublishRecord (TierKey, ProductId, PageKey, StoryKey, PublishDate, ChapterKey)
VALUES ('liesijznoo', 'prod_oOcEiHmKEh04Ag', 'lies5yw6p3', 'liyy27t7t7', NOW(), @cid);

COMMIT;

3. 添加明确的唯一约束并处理冲突

如果PublishRecord还没加组合唯一约束,先补上:

ALTER TABLE PublishRecord ADD UNIQUE INDEX idx_tier_chapter (TierKey, ChapterKey);

之后可以在插入时用ON DUPLICATE KEY UPDATE避免报错(比如更新PublishDate),或者捕获冲突后自动重试插入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:33:01