如何实现幂等性-前置条件和校验操作id

260 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

设置数据更新的前置条件

为数据设置一个更新的前置条件,例如:当某个字段等于某个值时,才会进行更新否则不会更新数据,等同于版本号的概念。

并且第一次更新的时候,前置条件满足,更新条件成立,更新的同时会把前置条件也一并更新为新的值,这样在重复执行操作时,由于首次更新已经将前置条件值改变,则不会有重复更新的情况存在。

举例说明: 场景:账户A向账户B转账100元。 增加前置条件:余额为200元的账户A,向余额为300元的账户B转账100元。

那么在操作A账户时,首先会判断账户A的余额是否为200元,是的话则对A的账户进行余额扣除100元;同理,在操作B账户的时候也会进行相同的判断。有了这种机制,就保证了这个操作的幂等性,不会因为重复消费消息而造成影响。

但是当例如并发的情况:余额为200元的账户A,向余额为300元的账户B转账100元。余额为400元的账户C向余额为200元的账户A转账100元;或者是其他复杂的操作,还能用此种方法保证幂等性吗?

答案是肯定的,此时前置条件就不设置为账户的余额,可以设置一个版本号,当账户的余额发生变更时,则对版本号+1 ,这样一样可以保证幂等性。

操作id值检查

对每个操作都设置一个唯一的id,例如uuid,或者是分布式id,在执行数据更新操作之前,先根据操作的id检查一下是否执行过这个更新操作,如果已更新则不进行操作。

需要注意的一点是,在分布式系统中,多个实例同时拿到同一条消息进行消费时,需要避免两个实例在进行校验时得到的结果都是:未消费过,因为 校验消费状态-消费逻辑-更新消费状态 这个操作不具备原子性,需要通过分布式事务或者分布式锁进行保证。