谈谈幂等技术(一)
一、前言
幂等技术是为了保证唯一性,保证同一个请求只被处理一次的技术。处理幂等的技术有多种,本文我们就来看看如何基于幂等表来做幂等处理。
二、幂等处理
基于幂等表的方式,我们需要在数据库专门建立一个幂等表,表结构可以包含下面三个字段:
id,module,code
其中module标识业务模块
code标识幂等key,
另外我们需要在moudle和code两列建立唯一索引
2.1 方案一
基于上面幂等表我们看看方案一幂等处理流程:
插入幂等记录:module=业务模块,code为业务幂等key
执行业务流程,如果执行成功,则结束。如果失败,则删除步骤一插入的记录
当同一个请求(moudle和code一样)多次过来后,会先执行步骤1插入幂等记录,介于唯一性约束,只有一个请求会插入成功,其他请求会抛出唯一键冲突异常。这保证了步骤2只会执行一次。
上面方案看起来可行,但是考虑如果步骤一执行OK,在执行步骤2时候机器挂了,则会导致幂等记录不能被删除,这样会导致重复的请求过来后被幂等掉,从而导致请求被漏处理。
2.2 方案二
幂等处理流程:
开启事务
插入幂等记录:module=业务模块,code为业务幂等key
执行业务流程
提交/回滚事务
不同于方案一,方案二让插入幂等记录和业务处理放到了一个事务内。这样当业务逻辑执行完成,则把幂等记录插入db,执行失败则回滚幂等记录。
那么一个问题是,开启事务本身是有开销的,是否可以在开启事务前先select一把,看看是否存在幂等记录,存在则直接返回那?这时候幂等流程为:
根据module=业务模块,code为业务幂等key查询是否存在记录,存在则直接返回,否则继续下面流程。
开启事务
插入幂等记录:module=业务模块,code为业务幂等key
执行业务流程
提交/回滚事务
这种方案是可行的,但是要看具体场景,如果需要被幂等掉的请求比较少,那么就没必要先select一把,因为事务外加select会导致所有请求都select一把。如果需要被幂等的请求量比较大,那么事务外先select一把是不错的选择。
三、总结
本文我们概要介绍了,基于幂等表进行幂等处理的方式,欢迎大家留言讨论。