zoukankan      html  css  js  c++  java
  • 锁的介绍

    Ⅰ、锁的概念

    1.1 锁的作用

    • 对共享资源进行并发访问
    • 提供数据的完整性和一致性

    1.2 锁的实现

    每个数据库的锁的实现完全不同

    • MyISAM表锁
    • InnoDB行级锁
      Like Oracle???不一样
    • Microsoft SQL Server 行级锁with锁升级
      行锁超过5000个就升级为行级锁或者表锁

    MySQL做的很棒,但是很难理解。

    1.3 latch(闩锁)

    • mutex 互斥锁
    • rw-lock

    他们是锁吗?

    latch在内存中,控制内存数据结构的并发访问,针对程序内部资源(比如:全局变量),锁的是并发资源(临界区),lock是数据库层的锁,针对的是事务,锁的对象不是内存结构而是行

    数据库中发生死锁会选择一个事务回滚,程序层中没有死锁检测

    latch无处不在,对某一个对象并发访问的控制,和lock也没啥好比较的,完全不搭界

    lock由latch来保证和实现

    tips:
    如何查看latch? 了解即可,基本用不着

    (root@localhost) [(none)]> show engine innodb mutex;
    +--------+---------------------------+----------+
    | Type   | Name                      | Status   |
    +--------+---------------------------+----------+
    | InnoDB | rwlock: dict0dict.cc:1184 | waits=3  |
    | InnoDB | rwlock: log0log.cc:838    | waits=23 |
    +--------+---------------------------+----------+
    2 rows in set (0.00 sec)
    

    即使很大也没什么意义,代表不了什么,waits很长就代表这个latch有并发
    某时间点数据写入量很大,那重做日志的这把latch可能就会很大
    读取量大的话,bp的latch可能会很大

    Ⅱ、 演示锁

    session1:
    (root@localhost) [test]> show create table lG
    *************************** 1. row ***************************
           Table: l
    Create Table: CREATE TABLE `l` (
      `a` int(11) NOT NULL,
      `b` int(11) DEFAULT NULL,
      `c` int(11) DEFAULT NULL,
      `d` int(11) DEFAULT NULL,
      PRIMARY KEY (`a`),
      UNIQUE KEY `c` (`c`),
      KEY `b` (`b`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    1 row in set (0.00 sec)
    
    (root@localhost) [test]> select * from l;
    +---+------+------+------+
    | a | b    | c    | d    |
    +---+------+------+------+
    | 2 |    4 |    6 |    8 |
    | 4 |    6 |    8 |   10 |
    | 6 |    8 |   10 |   12 |
    | 8 |   10 |   12 |   14 |
    +---+------+------+------+
    4 rows in set (0.00 sec)
    
    (root@localhost) [test]> begin;
    Query OK, 0 rows affected (0.00 sec)
    
    (root@localhost) [test]> delete from l where a = 2;
    Query OK, 1 row affected (0.00 sec)
    
    (root@localhost) [test]> update l set b = b + 1 where a = 4;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    (root@localhost) [test]> select * from l;
    +---+------+------+------+
    | a | b    | c    | d    |
    +---+------+------+------+
    | 4 |    7 |    8 |   10 |
    | 6 |    8 |   10 |   12 |
    | 8 |   10 |   12 |   14 |
    +---+------+------+------+
    3 rows in set (0.00 sec)
    
    此时这两条记录上就被加了排他锁,在当前session看到这两条记录已经变化了
    

    再开一个session看到的还是原来的记录,因为事务还没提交,mvcc特性

    session2:
    (root@localhost) [test]> select * from l;
    +---+------+------+------+
    | a | b    | c    | d    |
    +---+------+------+------+
    | 2 |    4 |    6 |    8 |
    | 4 |    6 |    8 |   10 |
    | 6 |    8 |   10 |   12 |
    | 8 |   10 |   12 |   14 |
    +---+------+------+------+
    4 rows in set (0.00 sec)
    
    (root@localhost) [test]> show engine innodb statusG
    ...
    LIST OF TRANSACTIONS FOR EACH SESSION:
    ---TRANSACTION 29474225, ACTIVE 46 sec
    2 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
    MySQL thread id 296696, OS thread handle 140076853794560, query id 34555618 localhost root
    Trx read view will not see trx with id >= 29474796, sees < 29474796
    ...
    
    通常认为增删改会加排它锁,其实select也可以加,select后面用一个for update就对这条记录加锁了,但是这个锁住了没事,新开session依然可以读,mvcc机制————默认读永远不会被锁,即使你在全表更新
    
    但新开session去select也加for update这时候就会等待了
    
  • 相关阅读:
    elasticsearch _bulk api
    elasticsearch _update api 更新部分字段内容
    elasticsearch _create api创建一个不存在的文档
    sql之left join、right join、inner join的区别
    Eclipse FreeMarker 插件安装
    Linux下Tomcat服务器重启与关闭
    SQL JOIN的用法
    HttpClient请求
    Struts2学习笔记
    Tomcat长出现的内存溢出问题
  • 原文地址:https://www.cnblogs.com/---wunian/p/9117320.html
Copyright © 2011-2022 走看看