用户双击发送,同一 session_id 两个请求同时写历史,后到的把先到的回复覆盖,聊天记录少了一轮。乍看像缓存或者权限的锅,追下去往往不是。

redis-cli SET session:lock:abc 1 NX EX 5

追下去是这么回事:会话历史是读改写,没有加锁也没有版本控制。两个请求都基于同一份旧历史追加,后提交的覆盖前者。

「并发写同一会话」这类改动最怕改一半,回滚脚本先准备好,再动生产。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。别只看报错的最后一行,往上看几行,真正的起因通常在上面。

同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

具体做法是,按 session_id 加分布式锁 串行写入;或改成 append 语义 不要整份覆盖;消息表加自增序号 按序号排序;前端发送后禁用按钮 防重复提交。

验收就看一点,并发双击后历史里两条消息都在 顺序正确不被覆盖。

作者 9823189