--查看隔离级别
select @@global.tx_isolation, @@tx_isolation;
--修改隔离级别
set [session | global] transaction isolation level [ read uncommitted | read committed | repeatable read | serializable]
--设置全局隔离级别
set global transaction isolation level read committed;
--设置当前会话隔离级别
set session transaction isolation level read committed;
--开启事务
begin;
start transaction;
--禁用自动提交,每个SQL语句或者语句块所在的事务都需要显示"commit"才能提交事务
--autocommit = 1 这种模式会在每条语句执行完毕后把它作出的修改立刻提交给数据库并使之永久化.
set autocommit = 0;
--读锁或者写锁在事务提交时候释放
SELECT * FROM test WHERe id = 1 LOCK IN SHARE MODE //读锁
SELECt * FROM test WHERe id = 1 for update //写锁
快照读:
select * from test where id = 1001;
1.读未提交:忽略
2.读已提交:不加锁
3.可重复读:不加锁
4.串行化:加读锁(范围如下)
4.1.数据存在且Mysql使用索引
(1)id为主键: 锁一条记录
(2)id为唯一索引:锁一条记录
(3)id为普通索引:gap key(左开右开) +record lock
(4)id无索引:gap key(所有gap锁) + record lock(所有记录)
4.2. 数据不存在且使用索引
(1)id为主键:gap锁(左开右开)
(2)id为唯一索引:gap锁(左开右开)
(3)id为普通索引:gap key(左开右开)
(4)id无索引:gap key(所有gap锁) + record lock(所有记录)
4.3. 不适用索引
gap key(所有gap锁) + record lock(所有记录)
当前读:
select * from test where id = 1 lock in share model(读锁)
select * from test where id = 1 for update(写锁)
insert test values(x,x,x,x)(写锁)
delete from test where id = 1(写锁)
update test set id = x where id = 1(写锁)
各种隔离级别的下的表现
1.读未提交:忽略
2.读已提交:加锁
2.1.数据存在且Mysql使用索引
(1)id为主键: 锁一条记录
(2)id为唯一索引: 锁一条记录
(3)id为普通索引: record lock
(4)id无索引: record lock(所有记录)(会迅速优化成对指定记录加锁)
2.2. 数据不存在且使用索引
(1)id为主键:无锁
(2)id为唯一索引:无锁
(3)id为普通索引:无锁
(4)id无索引:无锁
2.3. 不适用索引
结果集加锁
------------ 读已提交 只对查找出来的结果集加锁,不会加间隙锁,不保证可重复度---------
3.可重复读:加锁
3.1.数据存在且Mysql使用索引
(1)id为主键: 锁一条记录
(2)id为唯一索引:锁一条记录
(3)id为普通索引:gap key(左开右开) +record lock
(4)id无索引:gap key(所有gap锁) + record lock(所有记录) ----(整张表不能insert)----
3.2. 数据不存在且使用索引
(1)id为主键:gap锁(左开右开)
(2)id为唯一索引:gap锁(左开右开)
(3)id为普通索引:gap key(左开右开)
(4)id无索引:gap key(所有gap锁) + record lock(所有记录)----(整张表不能insert)----
3.3. 不适用索引
gap key(所有gap锁) + record lock(所有记录)----(整张表不能insert)----
-----当索引区分度不高或者强制类型转换等导致没有索引失效,给全部记录加锁------
4.串行化:加读锁(范围如下)
4.1.数据存在且Mysql使用索引
(1)id为主键: 锁一条记录
(2)id为唯一索引:锁一条记录
(3)id为普通索引:gap key(左开右开) +record lock
(4)id无索引:gap key(所有gap锁) + record lock(所有记录)
4.2. 数据不存在且使用索引
(1)id为主键:gap锁(左开右开)
(2)id为唯一索引:gap锁(左开右开)
(3)id为普通索引:gap key(左开右开)
(4)id无索引:gap key(所有gap锁) + record lock(所有记录)
4.3. 不适用索引
gap key(所有gap锁) + record lock(所有记录)
MySQL-InnoDB锁分析
可重复度隔离级别下,两个线程可以同时对不存在的数据加锁,且都能成功,都加锁后,任一个线程插入会等待,若另一个线程也插入,则会死锁