什么叫接口幂等性
系统中一个接口运行多次和运行一次的效果是一样的, 防止重复操作
比如, 多次点击提交订单按钮, 后台只生成一条订单; 支付时, 由于网络问题重发,应该只扣一次钱
删除业务的幂等性
先查询, 有再删除
public int delUser(Integer userId) { User user = userMapper.selectByPrimaryKey(userId); if (user!=null){ log.info("用户存在,用户为:"+userId); return userMapper.deleteByPrimaryKey(userId); } log.info("用户不存在存在,用户为:"+userId); return 0; }
更新业务的幂等性
加一个版本号version字段, 每次修改都+1, 并且每次修改都需要带上version字段作为条件
插入业务的幂等性
使用分布式锁
依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.14</version> </dependency>
定义ZkConfig
@Configuration public class ZkConfig { @Bean(initMethod="start",destroyMethod = "close") public CuratorFramework getCuratorFramework() { RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy); return client; } }
插入保证幂等性
@Service @Slf4j public class UserService { @Resource private UserMapper userMapper; @Autowired private CuratorFramework zkClient; public int insertUser(User user, String token) throws Exception { InterProcessMutex lock = new InterProcessMutex(zkClient, "/"+token); boolean isLock = lock.acquire(30, TimeUnit.SECONDS); if (isLock){ return userMapper.insertSelective(user); } return 0; } }
这种使用分布式锁结合token保证幂等性, 适用于所有场景