在数学里,幂等有两种主要的定义:在某二元运算下,幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。如,乘法运算下,0和1符合的自乘运算符和幂等,即s*s=s某一元运算为幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。例如,高斯符号便是幂等的,即f(f(x))=f(x)在计算机中,表示对同一个过程应用相同的参数多次和应用一次产生的效果是一样,这样的过程即被称为满足幂等性在分布式和前后端分离的的项目中,对于restful风格的接口,我们需要保证其接口的幂等性,说白了就是就是一个接口被反复调用不会影响最终结果;为什么呢,因为前后端分离的项目可能会发生这样的场景:前端发出一个请求,但这个请求被阻塞了,然后其重试机制再次发起请求,而恰好此时被阻塞的那个请求又好了,那么这个时候,会对后端发起连续两次请求;对于 get,put,delete 都没问题,连续的两次或者三次都不会影响请求处理结果,但post就有问题了;它会往数据库插入两条数据。
这显然不是正确的处理结果。在分布式和前后端分离的项目中,前端数据对后端来说都是不可信的。因此有一个机制来保证接口的幂等性是很有必要的。按照restful规范定义的接口,使用http方法,应该严格遵循http方法语义:方法幂等性对应CRUD操作POST不安全且不幂等CGET安全且幂等RPUT不安全但幂等UDELETE不安全但幂等D幂等实现方法:使用全局唯一ID:(数据库唯一索引,或者redis保存一个key)就是根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存储系统中,比如数据库、Redis等。如果存在则表示该方法已经执行。使用全局唯一ID是一个通用方案,可以支持插入、更新、删除业务操作。但是这个方案看起来很美但是实现起来比较麻烦,下面的方案适用于特定的场景,但是实现起来比较简单。去重表:这种方法适用于在业务中有唯一标的插入场景中,比如在以上的支付场景中,如果一个订单只会支付一次,所以订单ID可以作为唯一标识。这时,我们就可以建一张去重表,并且把唯一标识作为唯一索引,用以记录订单支付信息,在我们实现时,把创建支付单据和写入去去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。这个方法其实也是用到唯一ID,与上面全局唯一ID不同的是,他是针对具体单个业务流程的,实现起来相对简单。版本控制:对数据库表加入版本号形成乐观锁,更新操作时必须拿到正确的版本号才能更新成功。