开发者社区> 问答> 正文

sql语义合并的潜在风险

我们在项目中使用了DbLoadAction.java和相关代码,主要是用于入库的sql语义合并。测试时发现这样一个case出现问题:

1.insert一条记录

2.delete这条记录并立刻再insert同一id的记录

这样操作后,从库中的记录还是第一次insert的记录。原因是第二步操作的delete和insert被合并了,因此直接执行了insert,但因为id冲突,所以没有执行成功。

当然,线上一般没有这样的sql,不过这是个潜在的风险。

原提问者GitHub用户 melonboy312

展开
收起
大圣东游 2023-06-21 17:18:33 54 0
2 条回答
写回答
取消 提交回答
  • otter针对insert,默认会执行merge sql,针对有pk约束冲突的,第二次的insert会变为update,将当前insert的最新值更新到db中,结果最终还是一致的.

    主要考虑原始表中有A,B两条记录,其中有唯一约束a,b两列,现在想交换一下两者位置,一般做法是:update a -> c , update b->a , update c-> b, 因为并行导入顺序不确定性,update会出现乱序,出现约束冲突,规避的办法: delete a , delete b , insert b , insert a. otter会优先确保delete优先于insert执行,insert优先于update执行

    原回答者GitHub用户agapple

    2023-06-21 18:16:05
    赞同 展开评论 打赏
  • 确实,使用DbLoadAction的sql语义合并有时会导致潜在的风险。在您提到的情况下,由于insert和delete被合并,导致insert失败,这可能会导致数据不一致。

    为了避免这种情况,建议您在使用DbLoadAction时,尽量避免同时执行insert和delete操作,或者将它们分开执行。另外,您也可以考虑使用其他的数据同步工具,例如Canal,它可以解析binlog并将数据同步到目标库中,不需要使用sql语义合并,能够更好地保证数据的一致性。

    如果您仍然需要使用DbLoadAction,可以考虑对您的业务逻辑进行调整,例如在执行delete操作后等待一段时间再执行insert操作,以确保delete操作已经生效。同时,您也可以在代码中添加一些判断逻辑,以避免数据冲突和数据不一致的情况。

    2023-06-21 17:22:24
    赞同 展开评论 打赏
问答分类:
SQL
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载