分享

如何保证接口幂等性?常见方法哪些?

 笑笑兔 2023-09-13

前言

幂等性只是数学里面的概念,被用于计算机领域,表示任意多次请求均与一次请求执行结果相同。说白了就是接口,无论调用多少次,最终的结果一样。

幂等性实现方案分为以下几类:

  • 前端拦截

  • 使用数据库实现幂等性

  • 使用 JVM 锁实现幂等性

  • 使用分布式锁实现幂等性

一、前端拦截

用户在执行完(保存、修改)操作后,将按钮设置为不可用状态,避免用户重复点击。

二、数据库幂等性方案

  • 悲观锁来实现幂等性

使用悲观锁实现幂等性,一般是配合事务一起来实现,在没有使用悲观锁时,我们通常的执行过程是这样的,首先来判断数据的状态,执行 SQL 如下:

select status from table_name where id='xxx';

然后再进行添加操作:

insert into table_name (id) values ('xxx');

最后再进行状态的修改:

update table_name set status='xxx';

但这种情况非原子操作,所以在高并发环境下可能会造成被执行两次的问题

改为事务后:

begin;  # 1.开始事务
select * from table_name where id='xxx' for update; # 2.查询状态
insert into table_name (id) values ('xxx'); # 3.添加操作
update table_name set status='xxx'; # 4.更改操作
commit; # 5.提交事务

注意:数据库必须innodb存储引擎,id字段必须主键或唯一索引,不然会锁表

  • 唯一索引来实现幂等性

创建一个唯一索引的表来实现幂等性,在每次执行业务之前,先执行插入操作,因为唯一字段就是业务的 ID,因此如果重复插入的话会触发唯一约束而导致插入失败。在这种情况下(插入失败)我们就可以判定它为重复提交的请求。

  • 乐观锁来实现幂等性

乐观锁是指在执行数据操作时(更改或添加)进行加锁操作,其他时间不加锁,因此相比于整个执行过程都加锁的悲观锁来说,它的执行效率要高很多。

乐观锁可以通过版本号来实现,例如以下 SQL:

update table_name set version=version+1 where version=0;

三、JVM锁实现

JVM 锁存在的最大问题在于,它只能应用于单机环境,因为 Lock 本身为单机锁,所以它就不适应于分布式多机环境。

总结

幂等性可以防止垃圾数据或者无效请求,对系统资源的消耗。常见方式包括前端拦截、数据库悲观锁实现、数据唯一索引实现、数据库乐观锁实现、JVM 锁实现等方案。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多