数据库每天都产生完全一致的重复数据,2条或者3条都有,sql逻辑是先更新,如果更新为0则插入

【 TiDB 使用环境】生产环境
【 TiDB 版本】5.4
【复现路径】保存或者更新操作
【遇到的问题:问题现象及影响】
【资源配置】
数据库每天都产生完全一致的重复数据,2条或者3条都有,sql逻辑是先更新,如果更新为0则插入

能用SQL重现吗?或者看看代码逻辑

按照你的描述,看看使用insert into on duplicate key update 语义能否满足业务需要。

1 个赞

完全重复,表没有主键吗

我的理解是你们应该是并发导致的,
session 1
sql1: update test set a=1 where a=0;—返回结果0
sql2: insert test(a) values (1);
session 2
sql1: update test set a=1 where a=0;—在session2 sql2执行完执行,返回结果1;—在session2 sql2执行前执行,返回结果0
sql2: insert test(a) values (1);—在session2 sql2执行完不执行,在session2 sql2执行前执行,导致插入重复
那只要session1和session2的sql1并行执行,sql2就都会执行啊

这个设计就很怪,一般来说这种应该做成一个事务
begin
select for update
判断
insert 或者update
end

你需要注意,tidb的默认事务隔离级别是RR.不是RC.

https://docs.pingcap.com/zh/tidb/stable/transaction-isolation-levels#可重复读隔离级别-repeatable-read

当事务隔离级别为可重复读时,只能读到该事务启动时已经提交的其他事务修改的数据,未提交的数据或在事务启动后其他事务提交的数据是不可见的。对于本事务而言,事务语句可以看到之前的语句做出的修改。

强烈建议优化一下业务场景 然后根据需求可调整Tidb默认事务隔离级别

本来就可以动态调整啊,在session级别设置就行

可以,虽然没太懂问题是什么。。。

这个需要唯一索引吧,但是有唯一索引的话也不会插入重复的数据

相同数据请求并发导致的

除主键外的重复

是并发导致的,但是你的解决方式没看懂

调整成什么级别?并发导致的

先更新没有再插入可以用replace into

这个需要唯一索引或者主键吧,但是更新的维度不是

试一下REPLACE into加主键,别用原来的方式了

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。