zoukankan      html  css  js  c++  java
  • 乐观锁和悲观锁的概念(转)

    原文链接:http://www.cnblogs.com/Sinte-Beuve/p/7631745.html

    之前一直不知道乐观锁和悲观锁是个啥东西。

    前面的记忆中乐观锁是基于version实现的,以前看过文章svn的版本控制就是用了这种方式。

    但也仅仅局限于那里。至于共享锁和排它锁的概念也是半桶水。

    原文中出现的问题是:并发下单问题。

    提出解决方案:队列和加锁

    乐观锁(Optimistic lock):

      想法乐观,认为在自己操作数据库时不会发生冲突,取数据时不加锁,更新数据是进行加锁判断。

    悲观锁(Pessmistic lock):

      想法悲观,每次去拿数据的时候都认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想拿到数据都会block直到它拿到锁。传统的关系型数据库里就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁等。

    锁的sql实现:

    以mysql innodb为例子,因为mysql是支持行锁的。

      悲观锁:

        首先必须关闭mysql的自动提交数据,因为mysql默认启用autocommit模式

    set autocommit=0;

      

    • 共享锁(s锁)

        

    SELECT … LOCK IN SHARE MODE

    SELECT … LOCK IN SHARE MODE 在读取的行上设置一个共享锁,其他session可以读这些行,但在你的事务提交之前不可以修改它们。如果这些行里有被其他还没有提交的事务修改,你的查询会等到那个事务结束之后使用最新的值。

    • 排它锁(x锁)

         

    SELECT ... FOR UPDATE;

    索引搜索遇到的记录,SELECT ... FOR UPDATE; 会锁住行以及任何关联的索引条目,和你对执行那些update的语句相同。其他的事务会被阻塞在对这些行执行UPDATE操作,获取共享锁,或者从事务隔离级别读取数据等操作

     注:select 语句默认不加锁,而cud语句默认加排它锁。

      乐观锁:

        乐观锁也就是在更新的时候进行查询,通常是用一个version进行实现。   

    UPDATE ... WHERE...
    # 基于version的实现
    SELECT ..., verison FROM [table] WHERE id = #{id}
    UPDATE [table] SET..., version = version + 1 where id = #{id} AND version = #{version}

      

    索引搜索遇到的记录,SELECT … FOR UPDATE 会锁住行及任何关联的索引条目,和你对那些行执行 update 语句相同。其他的事务会被阻塞在对这些行执行 update 操作,获取共享锁,或从某些事务隔离级别读取数据等操作。一致性读(Consistent Nonlocking Reads)会忽略在读取视图上的记录的任何锁。(旧版本的记录不能被锁定;它们通过应用撤销日志在记录的内存副本上时被重建。)

  • 相关阅读:
    vi/vim 如何添加和删除多行注释
    linux报错:命令未找到
    删除远程分支的方法
    k-vim常见快捷键
    [转]常见linux命令用法介绍
    python库termcolor用法
    gitignore样例解析
    [转]"git rm" 和 "rm" 的区别
    python中的slice用法
    牛客网linux试题-错误整理-20170914
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/7644183.html
Copyright © 2011-2022 走看看