• Mysql锁机制


    一、锁的定义

      读锁(共享锁):是多事务可以并发读取数据的锁,但任何事务都被阻塞等待对该数据进行写操作和加写锁,直到已释放所有共享锁。

      写锁(排他锁):是指只有当前事务才可以进行读写操作的锁,则其他事务都被阻塞等待对该数据进行读写操作和加读写锁,直到已释放所有排他锁。

    二、锁特点 

    •   表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
    •   行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
    •   页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

    三、MyISAM表锁

      MyISAM 存储引擎只支持表锁,MySQL 的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。

         读操作:一旦数据表被加上读锁,当一个请求在读数据时,其他请求也可以读,但是不能写,因为一旦另外一个线程写了数据,就会导致当前线程读取到的数据不是最新的了。这就是不可重复读现象。

      写操作:一旦数据表被加上写锁,当一个请求在写数据时,其他请求不能执行任何操作,因为在当前事务提交之前,其他的请求无法看到本次修改的内容。这有可能产生脏读、不可重复读和幻读。

      读锁和写锁都是阻塞锁:例如A对数据表增加了写锁,如果B请求对数据表加写锁,此时B的加锁请求会一直处于阻塞状态,直到A释放了对表的锁,B才加锁成功获取到结果。

    四、表锁的加锁/解锁方式

      MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作 (UPDATEDELETEINSERT 等)前,会自动给涉及的表加写锁;因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。

      锁表:lock tables tbl_name read | wrinte,tbl_name1 read | wrinte,

      解锁表:unlock table

      查看表加锁状态:show open tables like '%tbl_name%';

      

       注意:当某事务在执行 LOCK TABLE 后,只能访问加锁的这些表,该事务不能访问未加锁的表,其他事务可以访问未加锁的表;

      此外,Myisam的读写锁调度是写优先,因此Myisam不适合做写为主表的引擎,因为写锁后其他线程不能做任何操作,大量更新会使查询很难得到锁,从而造成永远堵塞。

    五、Innodb行锁

       行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。有可能会出现死锁的情况。行级锁也分为共享锁和排他锁。

    六、Innodb 行加锁方式:

      共享锁用法:select ... where id=1|2|3... lock in share mode;

      排它锁用法: select ... where id=1|2|3... for update;

    七、死锁

       MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。

    ​ 在InnoDB中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。 当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

      

     

  • 相关阅读:
    上传和下载附件功能
    C#小常识,持续更新..
    动态添加HTML表单控件,无(runat="server")
    Excel技巧 持续更新..
    JS函数集锦 持续更新..
    JS 函数 检验输入是否为数字类型,正整数
    存储过程 游标 事例
    Sql 查询语句中的类型转换
    shell 计数脚本
    centos 获取文件的创建时间
  • 原文地址:https://www.cnblogs.com/zgxblog/p/14145461.html
Copyright © 2020-2023  润新知