我们在项目中使用了DbLoadAction.java和相关代码,主要是用于入库的sql语义合并。测试时发现这样一个case出现问题:
1.insert一条记录
2.delete这条记录并立刻再insert同一id的记录
这样操作后,从库中的记录还是第一次insert的记录。原因是第二步操作的delete和insert被合并了,因此直接执行了insert,但因为id冲突,所以没有执行成功。
当然,线上一般没有这样的sql,不过这是个潜在的风险。
原提问者GitHub用户 melonboy312
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
确实,使用DbLoadAction的sql语义合并有时会导致潜在的风险。在您提到的情况下,由于insert和delete被合并,导致insert失败,这可能会导致数据不一致。
为了避免这种情况,建议您在使用DbLoadAction时,尽量避免同时执行insert和delete操作,或者将它们分开执行。另外,您也可以考虑使用其他的数据同步工具,例如Canal,它可以解析binlog并将数据同步到目标库中,不需要使用sql语义合并,能够更好地保证数据的一致性。
如果您仍然需要使用DbLoadAction,可以考虑对您的业务逻辑进行调整,例如在执行delete操作后等待一段时间再执行insert操作,以确保delete操作已经生效。同时,您也可以在代码中添加一些判断逻辑,以避免数据冲突和数据不一致的情况。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。