-
幂等问题引入与准备工作
- 幂等概念:幂等指多次操作影响仅与首次执行结果相同,重复执行不会对系统造成额外变化。
- 业务场景问题:以网站金币充值为例,因网络不稳定,支付宝支付成功的异步通知可能多次发送,若商家不做幂等操作,同一订单可能被多次处理,导致用户账户重复加钱。
- 准备工作:创建账户表和充值表用于测试。账户表包含账户id、名称、余额字段;充值记录表包含id、账户id、充值金额、充值订单状态、version字段(用于乐观锁),并插入测试数据。
-
幂等问题解决方案
-
方案一:条件判断更新状态:在
update
操作时,以status等于零作为条件判断。根据充值订单id查询记录,若状态为已处理则返回成功;否则开启事务执行update
,将status设为1且条件为原状态是零,根据影响行数判断执行结果,成功则给账户加钱。经100次并发请求压测,结果符合预期。 -
方案二:使用乐观锁:先判断订单是否处理过,未处理则开启事务,获取订单当前版本号。更新时将状态置为成功且版本号加一,条件是当前版本号等于期望版本号,根据执行结果影响行数判断是否成功,成功则给账户加钱。100次并发压测后,结果可靠。
-
方案三:添加唯一约束辅助表:添加一张有唯一约束字段的辅助表。根据幂等K查找记录,若已存在则直接返回成功;否则开启事务执行业务操作,并向辅助表插入记录。因辅助表字段唯一约束,并发操作时只有一个能成功插入,其他会抛出异常,以此保证业务操作幂等性。经100次并发压测,该方案解决了幂等性问题,被认为是通用方案,可在项目框架搭建初期推广。
-
方案四:分布式锁(适用于无数据库操作场景):判断业务是否执行过,若已执行则直接结束;未执行则尝试加锁。加锁成功后再次判断业务是否执行,未执行则执行业务并释放锁;加锁失败则提示系统繁忙,稍后重试 。可使用REDIS的分布式锁实现,未提供具体代码。
-