mysql InnoDB 引擎,看了网上文章都说悲观锁影响并发导致性能不好,我一直理解不了。不管是悲观锁还是乐观锁一般都要包裹在事务中,悲观锁 for update 对索引条件也只是行锁,并不影响正常读。乐观锁的 update 语句本身也是锁,需要在事务提交后才释放。大家帮忙解释下呢,为啥说乐观锁比悲观锁性能更好?
1
EminemW 2019-08-27 10:31:31 +08:00 via iPhone 2
悲观锁是操作前就锁上,乐观锁是提交的时候判断能不能提交,你说哪个占用时间长
|
2
xalilo OP @EminemW
正常的 select 不会受影响,只是对同样要修改的才需要 for update,悲观锁控制还能避免后续可能存在的一堆大量的业务逻辑的无效执行。 |
3
xalilo OP 想了下:
像库存扣减这种校验不为负的,需要多次修改,最后一次才会无效的用乐观。 像单据状态这种,变化少,每次都是互斥的用悲观锁更好? |
4
sutra 2019-08-27 11:11:08 +08:00
乐观锁并不需要“释放”。
|
6
tabris17 2019-08-27 11:27:33 +08:00
乐观锁 update 不是锁,MVCC 了解一下
|
7
ccagml 2019-08-27 12:08:58 +08:00 via Android
乐观锁不是根据一个数据版本号判断能不能更新?
|
8
Takamine 2019-08-27 12:43:09 +08:00 via Android
乐观锁有很多种实现,最简单的实现就是什么也不做。
哪个快。:doge: |
9
aliipay 2019-08-27 13:06:44 +08:00
个人认为,乐观锁适用于写少读多且写冲突后代价比较小的地方
|
10
zhze93 2019-08-27 13:09:11 +08:00
我认为,乐观锁更多的是提高并发读的能力吧,同时尽量保证数据可靠性。
|
11
fvckDaybyte2 2019-08-27 13:14:55 +08:00 via iPhone
眼花缭乱的术语……
|
12
xalilo OP @tabris17 MVCC 大概意思我了解一点,两个事务,第一个 update 未提交,第二个事务的 update 是会阻塞等待的,这里肯定是有锁的。
|
14
tabris17 2019-08-27 14:56:35 +08:00
@xalilo 乐观锁不开启事务的啊,只是利用 update 的原子性而已,你要说锁是否存在,当然也存在,毕竟 cas 操作本身也是一种锁,但是粒度小,所以可以并发高
|
16
DonaldY 2019-08-27 14:59:49 +08:00
唉
其实 update 也可以自动 commit 乐观锁是根据版本更新,即会 commit |
17
xalilo OP |
18
Aresxue 2019-08-27 17:35:54 +08:00 1
乐观锁其实不是常规意义上的锁,在编程语言中一般通过 CAS 机制去实现,在 mysql 中比较有名的是 MVCC,需要使用乐观锁的场景一般是读多写少的情况,不然一直自旋可能效果还不如悲观锁。
PS:MVCC 其实只能保证读的一致性,mysql 保证写一致性其实最后还是靠的 next-key |
19
haon 2019-08-27 18:47:05 +08:00
乐观锁没有加锁过程, 用户态即可完成, 加锁需要切换到内核态, 很慢
|
20
glogo 2019-08-27 20:26:23 +08:00 1
这其实很简单:
悲观锁——悲观地假设交织执行的事务之间会有冲突发生,那么一开始就先限制事务能拿到的锁,只有事务执行完释放了锁,另一个事务才能执行;否则,spin or fail. 乐观锁——乐观的假设交织执行的事务之间没有冲突发生,那么一开始就不限制事务的执行,等到事务要将更改写入磁盘(即 critial section 竞争区)时,才去判断这个事务能不能完成写入操作并释放锁;如果可以成功写入,那么就顺利退出,否则,事务执行失败 or spin for a while until succeed. 所以,为什么乐观锁比悲观锁性能更好呢?答案是,it depends,根据使用场景而定。 |