原 readPrivateMessages 走 select-then-update 两步:先按 status=UNREAD
查未读,再按 id in 翻转,maxReadId 取已 update 行的 max(id)。该实现
有两个问题:
1. select 与 update 之间到达的消息会被一并标 READ,但 maxReadId 取的
是 select 时刻的最大值,对方端拿到的「已读到哪条」语义偏弱,前端按
maxReadId 卡边界时也会与实际状态错位。
2. 接口与群聊 readGroupMessages(userId, groupId, messageId) 不对称。
改造:
- 接口签名增加 messageId(已读位置,含),与群聊接口对齐;
- mapper 替换为单条 update SQL:id <= messageId AND status=UNREAD 直接
翻转,消除两步竞态窗口;
- READ / RECEIPT 推送的已读位置直接采用前端上报的 messageId;
- 落地 ImPrivateMessageServiceImpl 原 TODO;
- 同步更新 testReadMessages_success / testReadMessages_noUnread。