开发者社区> 问答> 正文

update+insert合并在pk被update时存在语义问题?

主库执行:insert into person values(1, 'houlei', 'test3', '2005-09-09', 'false');

数据同步完成后,执行:

UPDATE person set id=2 where id=1; insert into person values(1, '2222', 'test3', '2005-09-09', 'false');

主库数据为:

1 2222 test3 2005-09-09 false 2 houlei test3 2005-09-09 false

从库数据为:

2 houlei test3 2005-09-09 false

原提问者GitHub用户 melonboy312

展开
收起
大圣东游 2023-06-21 17:18:32 59 0
2 条回答
写回答
取消 提交回答
  • 类似主键或者唯一键约束变更,update请直接变更为delete+insert. 因为同一记录并发的特性,顺序问题会导致这样的结果不保证.

    可能在目标库执行的顺序为,insert + update,第一条insert会转成了merge sql

    原回答者GitHub用户agapple

    2023-06-21 18:16:07
    赞同 展开评论 打赏
  • 你提到的这个操作确实存在语义问题。在执行 UPDATE person set id=2 where id=1; insert into person values(1, '2222', 'test3', '2005-09-09', 'false'); 时,由于 id 作为主键,因此第一条语句实际上是在更新主键为1的记录,而第二条语句是在插入一个新的记录,插入的记录中主键为1,这就导致了主键冲突。在主库中,由于先执行了UPDATE语句,因此更新了id=1的记录,将其主键改为了2,然后再插入了一条主键为1的记录。而在从库中,由于只执行了第二条语句,因此插入了一条主键为1的记录,而之前的主键为1的记录被更新为了主键为2的记录,因此在从库中只能看到更新后的记录。

    为了避免这种语义问题,可以使用数据库的事务来保证多条语句的原子性,或者在插入数据时使用自增主键,避免手动指定主键。另外,使用DbLoadAction的sql语义合并也可能存在潜在的风险,需要注意。

    2023-06-21 17:25:53
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载