• Mysql中的锁


    一、锁的概念

    锁是计算机协调多个线程并发访问某一资源的机制;

    在数据库中,数据也是一种供许多用户共享的资源,如何保证数据并发的一致性、有效性,是所有数据必须解决的一个问题,锁冲突也是影响数据访问性的一个重要因素。

    锁对数据库的性能而言显得尤为重要,也更加复杂。

    二、Mysql中的锁

    Mysql的锁机制比较简单,其中最显著的特点是不同的存储引擎,锁的机制不一样;

    比如:MyISAM和MEMORY存储引擎采用的是表级锁;

               InnoDB采用的行级锁,也支持表级锁,但是默认情况下是采用的行级锁。

    二、Mysql中的锁的特点

    1. 表级锁:

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

    2. 行级锁:

         开销大,加锁慢,会出现死锁;锁定粒度小,发生冲突的概率低,并发度高。

    3. 页面锁:

         开销和加锁时间介于行级锁 和 表级锁之间,会出现死锁;锁定粒度介于行级锁 和 表级锁之间;

    4. 使用场景:

         表级锁适合于查询为主,只有少量按索引条件更新数据的应用,如OLAP系统;

         行级锁则适合于有大量安索引条件并发更新少量不同的数据,同时又有并发查询的应用;

    三、MyISAM的表锁

    1. 锁的简单介绍:

    2. 锁定具体使用:

    加锁  lock table 表名 READ

    3. 具体事例:

    LOCK TABLE demomyisam READ

    3.1 先给表加读锁,

           结果:

    1.  在同一个session和另外的session,都是可以查询的;
    2.  在同一个session,不能做插入操作(更新操作也是同样的错误)
    3. (接着2 的操作)在另外的session,执行插入和更新操作会出现一直等待的情况,知道2中的解锁才行);

    4. 解锁操作:unlock tables;
    5. 对表 A 加锁,这时候不能创建另外的表;
    6. 对表 A 加锁,操作表 B ,同一个 session 执行插入和更新,都会报错(但是报错的信息和上一个是不一样的);
    7. 对表 A 加锁,操作表 B,不同的 session 执行插入和更新,都不会报错;

    8. mysql的锁,是不支持别名的;比如 加锁 LOCK TABLE demomyisam READ ,按说查询 demomyisam 是不会报错的,但是, SELECT * FROM demomyisam a ,就报错了;(结论:mysql的锁,是不支持别名的),这时候的话,需要这样加锁:LOCK TABLE demomyisam AS a READ 

    3.2 先给表加写锁 

    SELECT * FROM demomyisam

     四、InnoDb锁详解

    1. 行锁:

    • 读作,又称共享锁,当一个事务对某几行上读锁的时候,允许其他的事物对这几行进行读操作,但是不允许其他进行写操作,也不允许其他的事物给这几行上排它锁,但是允许上读锁;
    • 写锁,又称排它锁,当一个事务对某几行上写锁的时候,不允许其他的事物写,但是允许读,更不允许其他的事物给这几个行上任何锁,包括写锁;

    2. 加锁操作:

    上共享锁语法:lock in share mode

    SELECT * FROM 表名 WHERE (需要锁的条件) LOCK IN SHARE MODE;     

    排它锁语法:  for update 

    SELECT * FROM 表名 WHERE (需要锁的条件)FOR UPDATE;

    3. InnoDb 行锁的特点

    1.
    BEGIN
    select * from testdemo where id =1 for update
    在另外一个session中
    update testdemo set c1 = '1' where id = 2 成功
    update testdemo set c1 = '1' where id = 1 等待
    2.BEGIN
    update testdemo set c1 = '1' where id = 1
    在另外一个session中
    update testdemo set c1 = '1' where id = 1 等待
    3.
    BEGIN
    update testdemo set c1 = '1' where c1 = '1'
    在另外一个session中
    update testdemo set c1 = '2' where c1 = '2' 等待

    3. 表锁:

    和MyISAM差别不大,

    注意:开启一个事务的时候会解锁表;

    1.先来看下行锁
    第一个session中
    select * from testdemo where id =1 for update
    第二个session
    select * from testdemo where id =1 lock in share mode
    回到第一个session UNLOCK TABLES 并不会解锁
    使用commit 或者 begin或者ROLLBACK 才会解锁
    2.再来看下表锁
    lock table testdemo WRITE
    使用commit,ROLLBACK 并不会解锁
    使用UNLOCK TABLES 或者begin会解锁

  • 相关阅读:
    开始系统的研究区块链技术了
    基于Centos7的比特币源码编译
    WTForms
    flask-session
    抽屉之Tornado实战(5)--点赞与评论树
    零碎知识点
    flask信号
    MetaClass
    flask系列
    flask源码剖析--请求流程
  • 原文地址:https://www.cnblogs.com/lys-lyy/p/11169248.html
Copyright © 2020-2023  润新知