背景描述:我们系统A做远程在线接口提供给B系统调用,每次的请求参数中都带有幂等单号用来做幂等校验,幂等单号对应的字段是不可空且唯一的。由于对应的业务表线上已有数据,这个幂等字段数据新加的字段,所以要做初始化数据,给每条记录设置一个幂等值进去。

第1次的方案:在入参进来的时候根据查询方案selectCount了此幂等号对应的数据记录,首先不说selectCount方法的性能(全表扫描),其次这种提前的查询不支持并发的情况,并发情况下,插入的数据对插入的数据不可见的,这样就不能报账幂等,数据的唯一性。(被狠狠的diss了一顿)

第2次的方案:由于上面的方法不保险不可行,必须在数据库给幂等字段加唯一索引,而唯一索引的字段不可空,加上之前新增的幂等字段设置的可空,蚂蚁数据库限制,不可将可空的字段设置为不可空,所以又得新加字段,设置不可空为幂等字段,然后再在这个幂等字段上加唯一索引,然后在插入数据时,先插入数据,如果插入异常,而且是唯一键异常,则捕获此异常,给接口返回true。貌似这样的方法在线下没错误,实则是凭了运气。后续将下面。(线上唯一索引又没生效,并发导致重复数据进来,直接被批了一顿,幸亏数据可以删除,数据量不大)。

第3次的方案:为何第2次的方案不可行呢?因为唯一索引执行时,有条件的。1、字段值不能为空 2、字段值不能重复。再加上以为有数据库兜底的校验机制,就将代码查询校验的给去掉了,结果唯一索引也没有生效,索引幂等形同虚设。这是一次惨痛的教训,被喷成shit了。

正确的做法:以代码提前查询(找一个效率高的查询,不要全表扫描,数据量过大会影响性能的),再加上必须生效的唯一索引。

唯一索引执行成功的方法步骤:

          1、应该先加字段,

          2、然后初始化不同的值到幂等字段,

          3、然后再加唯一索引这样才会使得唯一索引生效。不能将表结构变更(添加字段和添加索引放在一起执行,这样的话唯一索引一定不成功)。

总结:这次反复在同一个问题犯错,想想原因:1、基础太差,并发不了解,数据库不了解唯一索引的用法 2、蚂蚁数据库线上和线下索引(两天才能生效)执行的不同 3、唯一索引执行生效的步骤不了解。