关于代码乐观锁和幂等使用

本文探讨了在处理大量并发请求时,如何利用乐观锁和幂等性来确保数据库数据的一致性和安全性。通过举例说明乐观锁在订单状态变更和账户余额减少场景的应用,以及幂等性在接口设计中的重要性,强调了主键或唯一索引在防止重复处理和补偿机制中的作用,同时警告避免使用version字段进行业务更新。

当有大量请求业务,各种业务数据更新表,可能还有重复请求,等等因素会导致更新数据库发生重复执行,导致数据库数据的不一致。为了保证数据数据的安全和一致性,一般会采用乐观锁和幂等方式保证最后一道关口的数据一致。

乐观锁使用场景1:
业务流程状态发生变化: 比如 订单状态变更,从0 (初始状态) 变更成 1(已完成)
正常sql逻辑 : update order set status = 1 where id = 1 ;
加入乐观锁sql逻辑; update order set status = 1 where id = 1 and status =0 ;
如果订单状态已经发生变化了,这个乐观锁的sql肯定执行结果是0 ,说明这个请求是重复的或者异常的请求,直接回滚即可。如果未使用乐观锁,假如这时候订单状态已更新成2 (已取消),又会把订单更新成1 。

乐观锁使用场景2:
当金额发生减少时候避免金额减成负数:比如 account账户余额1000,付款减余额1000。
正常sql逻辑1: 
select Balance from account where id =1;
int M = Balance -1000;
update account set Balance = M where id =1;

正常sql逻辑2: 
update account set Balance = Balance -1000 where id =1;

乐观锁sql逻辑: update account set Balance = Balance -1000 where id =1 and  Balance -1000 >=0 ;

如果发生并发,减少2次余额,那么使用乐观锁sql 执行,只有有一条执行成功结果是1,另一条肯定执行结果是0。

幂等使用: 当sql使用行级乐观锁的控制以后,很多service方法执行时候间接保证了单个的方法幂等。
对于还有很多外部系统之间的调用,也需要被他人调用是幂等,或者要求被调用方的接口保证幂等。不管调用还是被调用,只要接口幂等,就不会发生同一个订单被重复处理2次。还方便业务进行补偿机制,当出现网络异常,或者服务异常的时候,再次调用不会发生重复处理的问题。
一般使用主键或者唯一索引,比如我们订单支付成功以后,我们给支付宝提供的订单编号肯定在我们这边是唯一的,支付成功以后,第三方支付会异步回调我们的服务,告诉我们支付结果。我们根据支付结果处理订单状态和其他业务操作,如果网络异常,第三方支付多次请求我们的异步回调结果,我们通过状态控制,对于业务操作只会执行一次。
反过来,如果我们调用第三方支付时候,网络异常或者其他问题发送多个相同订单支付,第三方支付系统只会根据我们的订单号查询是否有此单的支付,如果没有就写入库(如果有唯一索引或者主键控制相同的订单号写入肯定是失败,说明已经写入了),如果写入失败或者查询订单有此订单信息可以直接返回此订单的支付状态。

严禁使用version 版本号进行业务更新操作,当业务量大会导致大量数据更新失败。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值