锁是计算机协调多个线程或者线程并发访问某一资源的机制。
手动添加表锁:lock table 表名字 read | write,表名字2 read | write ......
释放表锁:unlock tables
查看表上加的锁:show open tables;
对room表加锁就会显示:
表共享读锁、表独占写锁
读锁:又称为共享锁,对同一份数据,多个读操作可以同时进行而互不影响。
若事务T对数据对象A加上读锁,事务T只能读A但不能修改A,其他事务只能对其加读锁,不可以加写锁,直到T释放A上的读锁为止。
当前session可以查询该表记录,不能查询其他没有锁定的表
其他session可以查询或者更新未锁定的表
其他session不可以更新该表(被锁的表)一直被阻塞,除非session1对表释放锁。
写锁:又称为排他锁,当前写操作没有完成前,它会阻断其他写锁和读锁。(写锁独占)
若事务T对数据对象A加上写锁,则只允许T读取和修改A,其他事务都不可以再对数据A再加任何类型的锁,直到T释放对A上的锁为止。
当前session可以对该表增删改,不可以操作其他未被锁的表;
其他session则不可以进行任何操作,一直被阻塞,除非session1对该表释放锁。
简而言之,就是读锁会阻塞写,但是不会阻塞读,而写锁则会把读和写都阻塞。
支持innodb、MYIsam,偏向MYIsam存储引擎
以查询为主、只有少量按索引条件更新数据的应用。
开销小,加锁快,不会出现死锁,发生所冲突的概率最高,并发度最低
偏向Innodb存储引擎,Innodb行锁是通过给索引上的索引项来实现的,意味着:只有通过索引条件检索数据。
话句话说就是:在一张表中有索引才会使用行锁,否则innodb将使用表锁。
支持的存储引擎:InnoDB
InnoDB与MyIsam的最大区别有两点:InnoDB支持事务和InnoDB支持行级锁。
3.2、特点
sesson1 | session2 |
更新但是session1没有提交: |
session2也是同样操作id=1的数据行:被阻塞,只能等待(下面是阻塞久了) |
session1提交更新: |
解除阻塞,更新正常进行 提交commit |
如果session1操作id=1的数据行,session2操作id=2的数据行会怎么样?? | |
各自互不影响 |
各自互不影响 |
无索引行锁升级为表锁:
session1 | session2 |
在hangsuo表中没有索引: 对id=1的数据行加行锁: |
表被锁了,对表的增删改对不可以, 等待 |
提交commti: |
对之前的更新回滚,不提交。 |
【什么是间隙锁】
当使用范围条件而不是等值检索,并请求共享或者排它锁时,Innodb会给符合条件的已有的数据记录的索引项加锁,对于键值在条件范围中的记录但是表中没有记录,叫间隙。
Innodb会对这个”间隙“加锁,这个机制就叫”间隙锁。
危害:造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下可能对造成很大危害。
锁定某一行,其对该行的其他事务对其操作会被阻塞,除非锁定行的会话结束commit;
通过检查 innodb_row_lock状态变量分析系统上的行锁的争夺情况。
mysql> show status like 'innodb_row_lock%';
+-------------------------------+--------+
| Variable_name | Value |
+-------------------------------+--------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 418625 |
| Innodb_row_lock_time_avg | 32201 |
| Innodb_row_lock_time_max | 51886 |
| Innodb_row_lock_waits | 13 |
+-------------------------------+--------+
5 rows in set (0.00 sec)
五项中红色标明的是比较重要的:
Innodb_row_lock_current_wait :当前正在等待锁定的数量
Innodb_row_lock_time:从系统启动到现在锁定总时间长度
nnodb_row_lock_time_avg:每次等待所花的平均时间
Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花时间
Innodb_row_lock_waits :系统启动后到现在总共等待的次数
(1)悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
(2)乐观锁: 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
乐观锁适用于多读的应用类型,这样可以提高吞吐量。