INSERT ON DUPLICATE KEY UPDATE返回值引起的小乌龙

本文讲述了在使用 INSERT ON DUPLICATE KEY UPDATE 时遇到的返回值问题,分析了由于时间精度导致的冲突更新判断错误,并探讨了多种解决方案,包括变更返回值类型、细化时间精度和增加版本号。
摘要由CSDN通过智能技术生成

一、东窗事发

某个版本送测,测试大佬给提了一个缺陷,且听我描述描述:

  • 一个学习任务:

  • 两个一模一样的学习动态:

  • 产品定义:学习任务(生字学习)完成后,会在小程序生成一个动态,再次完成不重复生成

obviously,上边出现的两个动态不符合“罗辑”

二、排查看看

既然出现了两个动态,那就来看看动态的源头是不是生成了两个

1.先看动态生成的触发点

下边为简化版的伪代码

// student_id - learn_type 是唯一索引
val rt = execSql(
"""
INSERT INTO t_learn_state (student_id, learn_type, create_time, update_time)
VALUES ("bc6b5e6979af11e8a10c1c1b0d1c49aa",10,now(),now()) 
ON DUPLICATE KEY UPDATE update_time = now()
""")
//判断是否首次完成
if (rt == 1) {
    //发送完成MQ消息
    sendMq("StudyXXXTopic","ResourceFinish","bc6b5e6979af11e8a10c1c1b0d1c49aa finish 10")
}
复制代码

看起来没什么问题,难道是mq重复消费了?

2.看看mq的消息情况

直接看mq后台的消息记录:

可见有两条时间非常接近的mq消息,展开消息后发现内容是一致的,也就是重复生成了消息,而不是重复消费,怎么会这样呢?难道唯一索引没创建?

3.看看表中有多少条记录

only one!

也就是唯一索引是生效的,表中确实只有一条记录

4.难道对 INSERT ON DUPLICATE KEY UPDATE 理解有误?

首先确认了jdbc的链接参数并没有使用useAffectedRows=true,也就是该sql的返回值是matched的行数!(后文也是基于此进行的分析)
再经过几番搜索及请教大佬,返回值确实是这样子的:

  • 如果是新插入的记录,那么返回值是1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值