mysql 悲观锁 乐观锁

2019-08-27 10:20:59 +08:00
 xalilo

mysql InnoDB 引擎,看了网上文章都说悲观锁影响并发导致性能不好,我一直理解不了。不管是悲观锁还是乐观锁一般都要包裹在事务中,悲观锁 for update 对索引条件也只是行锁,并不影响正常读。乐观锁的 update 语句本身也是锁,需要在事务提交后才释放。大家帮忙解释下呢,为啥说乐观锁比悲观锁性能更好?

7751 次点击
所在节点    Java
22 条回复
EminemW
2019-08-27 10:31:31 +08:00
悲观锁是操作前就锁上,乐观锁是提交的时候判断能不能提交,你说哪个占用时间长
xalilo
2019-08-27 10:44:02 +08:00
@EminemW
正常的 select 不会受影响,只是对同样要修改的才需要 for update,悲观锁控制还能避免后续可能存在的一堆大量的业务逻辑的无效执行。
xalilo
2019-08-27 10:47:50 +08:00
想了下:
像库存扣减这种校验不为负的,需要多次修改,最后一次才会无效的用乐观。
像单据状态这种,变化少,每次都是互斥的用悲观锁更好?
sutra
2019-08-27 11:11:08 +08:00
乐观锁并不需要“释放”。
xalilo
2019-08-27 11:19:45 +08:00
@sutra update 语句本身也是有锁的,事务不提交,锁一直存在,为什么不需要释放?
tabris17
2019-08-27 11:27:33 +08:00
乐观锁 update 不是锁,MVCC 了解一下
ccagml
2019-08-27 12:08:58 +08:00
乐观锁不是根据一个数据版本号判断能不能更新?
Takamine
2019-08-27 12:43:09 +08:00
乐观锁有很多种实现,最简单的实现就是什么也不做。
哪个快。:doge:
aliipay
2019-08-27 13:06:44 +08:00
个人认为,乐观锁适用于写少读多且写冲突后代价比较小的地方
zhze93
2019-08-27 13:09:11 +08:00
我认为,乐观锁更多的是提高并发读的能力吧,同时尽量保证数据可靠性。
fvckDaybyte2
2019-08-27 13:14:55 +08:00
眼花缭乱的术语……
xalilo
2019-08-27 14:19:59 +08:00
@tabris17 MVCC 大概意思我了解一点,两个事务,第一个 update 未提交,第二个事务的 update 是会阻塞等待的,这里肯定是有锁的。
xalilo
2019-08-27 14:41:32 +08:00
@aliipay 悲观锁也不影响正常的读,能举个读多写少,很明显乐观比悲观好的例子吗
tabris17
2019-08-27 14:56:35 +08:00
@xalilo 乐观锁不开启事务的啊,只是利用 update 的原子性而已,你要说锁是否存在,当然也存在,毕竟 cas 操作本身也是一种锁,但是粒度小,所以可以并发高
angsheng
2019-08-27 14:59:32 +08:00
@zhze93 可能多核上乐观锁更好?
DonaldY
2019-08-27 14:59:49 +08:00


其实 update 也可以自动 commit

乐观锁是根据版本更新,即会 commit
xalilo
2019-08-27 17:01:13 +08:00
@tabris17
@DonaldY
怪我前提没说清楚,我想的都是要判断状态,后续有很多业务逻辑,没有事务不好回滚,默认必须有事务的。谢谢大家,就到这把
Aresxue
2019-08-27 17:35:54 +08:00
乐观锁其实不是常规意义上的锁,在编程语言中一般通过 CAS 机制去实现,在 mysql 中比较有名的是 MVCC,需要使用乐观锁的场景一般是读多写少的情况,不然一直自旋可能效果还不如悲观锁。
PS:MVCC 其实只能保证读的一致性,mysql 保证写一致性其实最后还是靠的 next-key
haon
2019-08-27 18:47:05 +08:00
乐观锁没有加锁过程, 用户态即可完成, 加锁需要切换到内核态, 很慢
glogo
2019-08-27 20:26:23 +08:00
这其实很简单:
悲观锁——悲观地假设交织执行的事务之间会有冲突发生,那么一开始就先限制事务能拿到的锁,只有事务执行完释放了锁,另一个事务才能执行;否则,spin or fail.
乐观锁——乐观的假设交织执行的事务之间没有冲突发生,那么一开始就不限制事务的执行,等到事务要将更改写入磁盘(即 critial section 竞争区)时,才去判断这个事务能不能完成写入操作并释放锁;如果可以成功写入,那么就顺利退出,否则,事务执行失败 or spin for a while until succeed.

所以,为什么乐观锁比悲观锁性能更好呢?答案是,it depends,根据使用场景而定。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/595450

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX