首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  Java

mysql 悲观锁 乐观锁

  •  
  •   xalilo · 110 天前 · 4034 次点击
    这是一个创建于 110 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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


    其实 update 也可以自动 commit

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

    所以,为什么乐观锁比悲观锁性能更好呢?答案是,it depends,根据使用场景而定。
        21
    xalilo   109 天前
    @glogo 如果有选择答案的那种,我要选你做全场最佳😄😄😄
        22
    glogo   108 天前
    @xalilo Thanks
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2428 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 12:47 · PVG 20:47 · LAX 04:47 · JFK 07:47
    ♥ Do have faith in what you're doing.