2 个回答
建防重表
有时候表中并非所有的场景都不允许产生重复的数据,只有某些特定场景才不允许。这时候,就可以使用防重表的方式。例如消息消费中,创建防重表,存储消息的唯一ID,消费时先去查询是否已经消费,已经消费直接返回成功。
状态机有些业务表是有状态的,比如订单表中有:1-下单、2-已支付、3-完成、4-撤销等状态,可以通过限制状态的流动来完成幂等。select * from user id=123 for update; update user set amount=amount+100,version=version+1 where id=123 and version=1;
分布式锁直接在数据库上加锁的做法性能不够友好,可以使用分布式锁的方式,目前最流行的分布式锁实现是通过Redis,具体实现一般都是使用Redission框架。
token机制请求接口之前,需要先获取一个唯一的token,再带着这个token去完
发布于:3周前 (08-21) IP属地:四川省
insert前先select
在保存数据的接口中,在 insert 前,先根据 requestId 等字段先 select 一下数据。如果该数据已存在,则直接返回,如果不存在,才执行 insert 操作。
加唯一索引加唯一索引是个非常简单但很有效的办法,如果重复插入数据的话,就会抛出异常,为了保证幂等性,一般需要捕获这个异常。如果是 java 程序需要捕获: DuplicateKeyException 异常,如果使用了 spring 框架还需要捕获: MySQLIntegrityConstraintViolationException 异常。
加悲观锁更新逻辑,比如更新用户账户余额,可以加悲观锁,把对应用户的哪一行数据锁住。同一时刻只允许一个请求获得锁,其他请求则等待。这种方式有一个缺点,获取不到锁的请求一般只能报失败,比较难保证接口返回相同值。
加乐观锁更新逻辑,也可以用乐观锁,性能更好。可以在表中增加一个 timestamp 或者version 字段,例如 version :在更新前,先查询一下数据,将version也作为更新的条件,同时也更新version:更新成功后,version增加,重复更新请求进来就无法更新了。
发布于:3周前 (08-21) IP属地:四川省
我来回答
您需要 登录 后回答此问题!