表级锁(MyISAM)
数据库MyISAM引擎用的是表锁
MySQL表级锁的锁模式
MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,
在执行更新操作(DML)前,会自动给涉及的表加写锁。
所以对MyISAM表进行操作,会有以下情况:
对MyISAM表的读操作(加读锁),不会阻塞其他进程(会话)对同一表的读请求,
但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。对MyISAM表的写操作(加写锁),会阻塞其他进程(会话)对同一表的读和写操作,
只有当写锁释放后,才会执行其它进程的读写操作。
读锁(共享锁)
(加锁:lock table tablelock read — 释放锁:unlock tables)
会话0给A表加了锁
0会话的操作:
- 可以对A表进行读操作、不能进行写操作。
- 如果给A表加了读锁、则当前会话只能对A表进行读操作。
其他会话的操作:
- 可以对其他表(A表以外的表)进行读、写操作。
- 对A表:读-可以,写-需要等待释放锁。
写锁(互斥锁)
(加锁:lock table tablelock write — 释放锁:unlock tables)
会话0给表加了锁:
0会话的操作:
- 当前会话可以对加了锁的表进行任何操作(CRUD);但是不能操作其他表
其他会话
其他会话的操作:
- 对会话0中加锁的表可以进行CRUD的前提是:等待会话0释放写锁。
查看哪些表加了锁
1 | show open tables ; |
1代表被加了锁
分析表锁定的严重程度
1 | show status like 'table%' ; |
Table_locks_immediate :即可能获取到的锁数
Table_locks_waited:需要等待的表锁数(如果该值越大,说明存在越大的锁竞争)
什么情况下使用MyISAM引擎
Table_locks_immediate/Table_locks_waited > 5000, 建议采用InnoDB引擎,否则MyISAM引擎
行锁(InnoDB)
前提:
—mysql默认自动commit; oracle默认不会自动commit ;
为了研究行锁,暂时将自动commit关闭; set autocommit =0 ; 以后需要通过commit
关闭事务自动提价之后,事务会自动开启。
读锁
读锁也叫共享锁:如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。获准共享锁的事务只能读数据,不能写数据。1
用法:SELECT … LOCK IN SHARE MODE;
写锁
写锁也叫排它锁:
如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。1
用法:SELECT … FOR UPDATE
有索引才有行锁
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!