首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

揭秘支付系统中对乐观锁、悲观锁、行级锁的抉择

锁通常应用在多个线程对一个共享资源进行同时操作,用来保证操作的有序性和正确性的同步设施。在笔者看来,锁的本质其实是排队,不同的锁排队的空间和时间不同而已,例如,Java的Synchronized的锁是在应用处理业务逻辑的时候在对象头上进行排队,数据库的锁是在数据库上进行数据库操作的时候进行排队,而分布式锁是在处理业务逻辑的时候在一个公用的存储服务上排队。

乐观锁

乐观锁是基于一种具有“乐观”的思想,假设数据库操作的并发非常少,多数情况下是没有并发的,更新是按照顺序执行的,少有的一些并发通过版本控制来防止脏数据的产生,具体过程为,在操作数据库数据的时候,对数据不加显式的锁,而是通过对数据的版本或者时间戳的对比来保证操作的有序性和正确性。一般是在更新数据之前,先获取这条记录的版本或者时间戳,在更新数据的时候,对比记录的版本或者时间戳,如果版本或者时间戳一样,则继续更新,如果不一样,则停止更新数据记录,这说明数据已经被其他线程或者其他客户端更新过了。这时候需要获取最新版本的数据,进行业务逻辑的操作,再次进行更新。

其伪代码如下。

乐观锁在统一时刻,只有一个更新请求会成功,其他的更新请求会失败,因此,适用于并发不高的场景,通常是在传统的行业里应用在ERP系统,防止多个操作员并发修改同一份数据。在某些互联网公司里,使用乐观锁在失败的时候再尝试多次更新,导致并发量始终上不去,是一个反模式。而且这种模式是应用层实现的,阻止不了其他程序对数据库数据的直接更新。

悲观锁

悲观锁是基于一种具有“悲观”的思想,假设数据库操作的并发很多,多数情况下是有并发的,在更新数据之前对数据上锁,更新过程中防止任何其他的请求更新数据而产生脏数据,更新完成之后,再释放锁,这里的锁是数据库级别的锁。

通常使用数据库的for update语句来实现。

悲观锁是在数据库引擎层次实现的,它能够阻止所有的数据库操作。但是为了更新一条数据,需要提前对这条数据上锁,直到这条数据处理完成,事务提交,别的请求才能更新数据,因此,悲观锁的性能比较低下,但是由于它能够保证更新数据的强一致性,是最安全的处理数据库的方式,因此,有些账户、资金处理系统仍然使用这种方式,牺牲了性能,但是获得了安全,规避了资金风险。

行级锁

不是所有更新操作都要加显示锁的,数据库引擎本身有行级别的锁,本身在更新行数据的时候是有同步和互斥操作的的,我们可以利用这个航级别的锁,控制锁的时间窗口最小,一次来保证高并发的场景下更新数据的有效性。

行级锁是数据库引擎中对记录更新的时候引擎本身上的锁,是数据库引擎的一部分,在数据库引擎更新一条数据的时候,本身就会对记录上锁,这时候即使有多个请求更新,也不会产生脏数据,行级锁的粒度非常细,上锁的时间窗口也最少,只有更新数据记录的那一刻,才会对记录上锁,因此,能大大减少数据库操作的冲突,发生锁冲突的概率最低,并发度也最高。

通常在扣减库存的场景下使用行级锁,这样可以通过数据库引擎本身对记录加锁的控制,保证数据库的更新的安全性,并且通过where语句的条件,保证库存不会被减到0以下,也就是能够有效的控制超卖的场景。

另外一种场景是在状态转换的时候使用行级锁,例如交易引擎中,状态只能从init流转到doing状态,任何重复的从init到doing的流转,或者从init到finished等其他状态的流转都会失败。

行级锁的并发性较高,性能是最好的,适用于高并发下扣减库存和控制状态流转的方向的场景。

但是,有人说这种方法是不能保证幂等的,比如说,在扣减余额场景,多次提交可能会扣减多次,这确实是实际存在的,但是,我们是有应对方案的,我们可以记录扣减的历史,如果有非幂等的场景出现,通过记录的扣减历史来核对并矫正,这种方法也适用于账务历史等场景。

在支付平台架构设计评审中,通常对交易和支付系统的流水表的状态流转的控制、对账户系统的状态控制,分账和退款余额的更新等,都推荐使用行级锁,而单独使用乐观锁和悲观锁是不推荐的。

更多的支付平台架构设计评审核心要点与最佳实践,请扫码加入艳鹏在gitchat的唠嗑节目。

如果你想进入金融支付行业

Fastpay快付

做第三方支付行业的精品公众号,提供第三方支付的业务知识、架构规划与实施、技术的核心要点和最佳实践。

快速关注,请猛扫下面二维码!

公众号 项目主页

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180225G0HK7900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券