python tornado框架 乐观锁和悲观锁的用法和区别

随着并发量的增加影响到我们数据时, 我们可以用MySQL的锁技术

悲观锁

悲观锁:与乐观锁相反,对每次的数据操作都保存悲观的态度,总是担心数据会被修改,所以在自己操作的时候会对数据上锁,防止在自己操作的时候被他人同时操作导致更新丢失。

在执行数据库操作的时候,会加一把锁, 事物提交后释放锁 (期间如果有别的线程进行数据库操作, 会阻塞, 如果一直占用资源不释放,其他线程就一直无法操作数据)

需配合MySQL的事物进行操作

使用方法

在数据库操作语句中加入for update 

如: select * from goods where id=1 for update

乐观锁

乐观锁:顾名思义,对每次的数据操作都保持乐观的态度,不担心数据会被修改,所以不会对数据进行上锁。

由于数据没有上锁,这就存在数据会被多人读写的情况。所以每次修改数据的时候需要对数据进行判断是否被修改过。

不会加锁, 但是更新的时候会进行判断, 判断跟原始的数据一不一样,返回受影响行数, 如果不一样,他会返回受影响的行数为0, 如果一样,会返回受影响的具体数量, 我们可以通过返回值,来采取对应的措施,比如回滚还是从新执行一遍

原理: 将 select 和 update 融为 一条语句, 并返回受影响的行数, 如果行数为0,说明别人已经把数据改了, 这个时候我们可以再尝试重新获取一下数据

使用方法(拿Django来说)

将 select 和 update 融为 一条语句 

GoodsSKU.objects.filter(id=sku_id,stock=orgin_stock).update(stock=new_stock, sales=new_sales)

总结:

1、乐观锁:

冲突比较少的时候, 使用乐观锁(没有悲观锁那样耗时的开销) 由于乐观锁的不上锁特性,所以在性能方面要比悲观锁好,比较适合用在DB的读大于写的业务场景。

2、悲观锁:

冲突比较多的时候, 使用悲观锁(没有乐观锁那么多次的尝试)对于每一次数据修改都要上锁,如果在DB读取需要比较大的情况下有线程在执行数据修改操作会导致读操作全部被挂载起来,等修改线程释放了锁才能读到数据,体验极差。所以比较适合用在DB写大于读的情况。

读取频繁使用乐观锁,写入频繁使用悲观锁。


            
            

本博客源码Github地址:

https://github.com/whisnos/myblog

请随手给个star,谢谢!

打赏

  1. #1楼

    yxh(2020年5月3日 15:07)
    11111111111111

评论