码迷,mamicode.com
首页 > 数据库 > 详细

【MySQL】所谓的乐观锁与悲观锁 񞈆

时间:2019-08-19 09:32:18      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:visit   提交   被锁   也会   成功   机制   数据库   假设   思想   

原文: http://blog.gqylpy.com/gqy/382

"## 乐观锁
总是认为不会产生并发问题,每次去取数据时总认为不会有其它线程对数据进行修改,因此不会上锁。
但是在更新时会判断其它线程在这之前有没有对数据进行修改,一般会使用版本号机制会CAS操作实现。

版本号方式
????????一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加1。当线程A要更新数据时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值与此时数据库中的version值相等,才会提交更新操作。否则将重新更新操作,直到更新成功。

sql核心代码:

update table set x=x+1, version=version+1 where id=#{id} and version=#{version};

CAS操作方式
????????即 comparse and swap 或者 compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当需要更新数据时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。

悲观锁

????????总是假设最坏的情况,每次取数据时都认为其它线程会修改,所以都会加锁(读锁,写锁,行锁),当其它线程要访问数据时,都需要阻塞挂起,可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在java中,synchronized的思想也是悲观锁。

Python Django项目中的用法:

# 将访问量加1
models.BlogInfo.objects.filter(id=id).select_for_update().update(visit=F('visit') + 1)
# select_for_update():行级锁,所有匹配的行将被锁定,直到事务执行结束
# 一般情况下,如果其它事务锁定了相关行,那么本查询将被阻塞,直到锁被释放
# 如果不想使查询被阻塞,可添加参数 nowait=True
# 如果其它事务持有冲突的锁,互斥锁,那么查询将引发 DatabaseError异常
# 你也可以使用参数 skip_locked=True 忽略锁定的行
# 但要注意的是:nowait=True 与 skip_locked=True 是互斥的,同时使用将抛出异常

"

原文: http://blog.gqylpy.com/gqy/382

【MySQL】所谓的乐观锁与悲观锁 񞈆

标签:visit   提交   被锁   也会   成功   机制   数据库   假设   思想   

原文地址:https://www.cnblogs.com/gqy02/p/11375023.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!