zoukankan      html  css  js  c++  java
  • MySQL 并发控制(锁得使用)

    导读

    并发问题:同一时刻进行读写,并发问题回引发数据不一致问题。

    解决并发问题:MySQL采用了锁定机制去解决并发问题

    锁的分类

      MySQL使用两种锁机制去解决问题:共享锁排他锁,也叫读锁或者写锁。

      • 共享锁、读锁:不影响其他连接的读,写会受影响
      • 排他锁、写锁:会不让其他连接进行读写

      MySQL针对不同的数据粒度,又分别使用表锁行锁进行锁定。

    锁的实现

      MySQL是使用MVCC(Multi-Version Concurrency Control)实现的(性能很好,其实并没有真正上锁)。

      • 悲观锁(真正上锁)
      • 乐观锁(通过一些递增的字段来控制逻辑上锁)

      MVCC这种机制是通过对一行数据的几个隐藏列进行操作实现的。

      B+树的数据行,其实每一行都要加上几个隐藏列(版本号,一条记录可能对应几个版本号,差不多可以这样理解,一个版本号,对应一个快照)

    服务层和存储引擎层

      服务层只是实现了表锁:

        加锁:lock table 表名 read(write),表名2 read(write)

        解锁:unlock tables;

      存储引擎层实现行锁(只有InnoDB和extraDB实现了行锁)

      存储引擎层和服务器层可能都实现了行锁,但是实现逻辑不一样,优先使用存储引擎层的实现。

      事务部分会隐式的去加行锁和表锁,其中这个表锁不是服务器层实现的表锁。

    行锁和表锁对比

      表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低

      行级锁:开销大,加锁慢;回出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最大

    MVCC并发控制,读操作分类

      在MVCC并发控制中,读操作可以分成两类:快照读(snapshot read)与当前读(current read)

      快照读,读取的记录的可见版本(有可能是历史版本),不用加锁。

      当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。

    快照读:简单的select操作,属于快照读,不加锁。

    select * from table_name where ?;

    当前读:特殊的操作,插入/更新/删除操作,属于当前读,需要加锁。

    select * from table_name where ? lock in share mode;
    select * from table_name where ? for update;
    insert into table_name values (...);
    update table_name set ? where ?;
    delete from table_name where ?;

      以上都属于当前读,读取记录的最新版本。并且读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。其中,除了第一条语句,对读取记录加S锁(共享锁)外,其他的操作,都加的事X锁(排他锁)。

    InnoDB和MyISAM最大区别

    InnoDB有行级锁和事务

  • 相关阅读:
    Trojan.DL.Agent.nxd和RootKit.Agent.yj木马清除
    Java中的格式化数值(eg:保留两位小数)
    Int16, Int32, Int64的一点感悟
    在win2003上设置asp网站
    WPF学习笔记.
    对WF工作流异常(Event on interface type for instance id cannot be delivered)的一点总结.
    创建,安装,调试 Windows Service
    灵活而又可怕的params参数数组
    (转) 输入码、区位码、国标码与机内码
    SQL Server 2008 未来将不再包含全文检索功能, 再研究此功能已经没多大意思了.
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/13126960.html
Copyright © 2011-2022 走看看