1.锁分类
    操作类型:
        a.读锁(共享锁):对同一个数据,多个读操作可以同时进行,互不干扰。
        b.写锁(互斥锁):如果当前些操作没有完毕,则无法进行其它的读、写操作。

    操作范围:
        a.表锁:一次性对一张表整体加锁。如M有ISAM存储引擎使用表锁,开销小、加锁快,无死锁;但锁的范围大,容易发生锁冲突、并发能力低。
        b.行锁:一次性对一条数据加锁。如InnoDB存储引擎使用行锁,开销大,加锁慢,容易死锁;锁的范围小,不易发生锁冲突,并发度高(很小概率发生并发问题:脏读、幻读、不可重复度、丢失更新)
        c.页锁:很少使用
        
2.表锁:MyISAM
    a.读锁(共享锁):对同一个数据,多个读操作可以同时进行,互不干扰。
        加锁:lock table 表名 read;
        释放锁:unlock tables;
        读锁结论:如果某一个会话对A表加了read锁,则该会话只能对A表进行读操作、不能进行写操作,对于其它表不能进行读、写操作。
                 其它会话:对所有表(包括A表)可以读操作,对A表之外的所有表有写操作。对A表的写等待(需要加锁会话释放锁,才会结束等待执行)。
    b.写锁(互斥锁):如果当前些操作没有完毕,则无法进行其它的读、写操作。
        加锁:lock table 表名 write;
        写锁结论:如果某一个会话对A表加了写锁,该会话可以对A表进行任何操作;但不能对其它表进行任何操作。
                 其它会话:对A表进行读、写操作要等待加锁会话释放锁。 
    c.MySQL表级锁的锁模式:
        MyISAM在执行查询语句(select)前,会自动给设计的所有表加读锁,在执行写操作前,会自动给涉及的表加写锁。
        对MyISAM表的读操作(加读锁),不会阻塞其它进程(会话)对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后, 才会执行其它进程的写操作。
        对MyISAM表的写操作(加写锁),会阻塞其它进程(会话)对同一表的读、写操作,只有当前锁释放后,才会执行其它进程的读写操作。                     
    d.分析表锁定:
        i.查看那些表加了锁:show open tables; #1代表被加了锁
        ii.分析表锁定的严重程度:show status like 'table%';
            Table_locks_immediate:立刻能获取到的锁数
            Table_locks_waited:需要等待的表锁数
            一般建议:Table_locks_immediate/Table_locks_waited >5000,建议采用InnoDB,否则使用MyISAM
        
3.行锁:InnoDB(MySQL自动提交,行锁需要把自动提交关闭 set autoconmmit =0;)
    a.某个会话对某条数据进行DML操作,其它会话需要等该会话结束事务(commit、rollback)后,才能对这条数据进行DML操作                 
    b.行锁是通过事务来解锁的   
    c.行锁注意事项:
        i)、如果没有索引,行锁会转为表锁。(索引失效也会转为表锁)
        ii)、行锁的一种特殊情况:间隙锁(行锁):值在范围内,但却不存在。
        iii)、如果有where,则实际加锁的范围就是where后面的范围(不是实际的值)
    d.行锁:InnoDB默认使用行锁
        缺点:比表锁性能损耗大
        有点:并发能力强,效率高
        因此建议:高并发用InnoDB,否则使用MyISAM。
    e.行锁分析
        show status like '%innodb_row_lock%';
            Innodb_row_lock_current_waits:当前正在等待锁的数量。
            Innodb_row_lock_time:等待总时长。从系统启动到目前一共等待的时间。
            Innodb_row_lock_time_avg:平均等待时长,从系统启动到目前平均等待时间。
            Innodb_row_lock_time_max:最大等待时长,从系统骑电动到现在最大一次等待时间。
            Innodb_row_lock_waits:等待次数。从系统启动到现在等待次数。
    f.通过for update给select语句加锁。注意不要自动提交(set autocommit = 0;|start transaction;|begin;)