线上出现了一个问题:mq同步某一功能的数据的时候,同一主键的数据会发多次。业务逻辑是,某一条数据过来后,我会先去数据库查是否存在了此uuid的数据,如果有的话更新,如果没有的话插入。由于同一主键的数据会发不止一次的mq,并且间隔时间非常小,所以就导致了,两条数据都进入了插入的逻辑里面。抛出主键冲突的异常。另外就算是进入到了不同的更新和插入的逻辑里面,有时会出现第二条数据先进来,然后第一条数据再进来,此时数据库里面更新的就是第一次的数据,就会产生了数据错误。
综合上述的描述,目前要解决的事情有:1、mq并发。2、数据存储顺序(前提:有标识能区分mq最新数据)。

基于上述描述准备用merge into 语句,用数据库层面的事物来保证数据的一致性。那么现在就来赘述一下merge into的一些用法

merge into 是用来进行合并表的,但因为其特性不同场合用法有以下几种
1、合并表
2、外部数据插入更新
3、用join表更新

1和3我这里就不赘述了,我使用到的是2这一类,最后经过改造我所用到的sql如下:
1 MERGE INTO mytable t1
2 USING dual ON ( t1.tuuid =?)
3 WHEN MATCHED THEN
4 UPDATE SET modify_date =?,
5 flg =?
6 WHERE flg != 'N'
7 WHEN NOT MATCHED THEN
8 INSERT (
9 uuid,
10 flg,
11 modify_date ) VALUES (?,?,?);
由于是外部更新,属于类型2只有一张表,所以在第2行引入伪表做关联条件。同时sql第6行判断的是mq的顺序,如果根据uuid发现表里面存在数据并且flg值为‘N’就表示mq过来后插入的是第二条数据,那么就不需要再做更新。(关键的地方是第2行【伪表】和第6行【merge语句可以在update语句里面写where条件】的改动)


Krupp
0 声望0 粉丝

java python