精通MySQL之锁篇 (2)

共享读锁(S):手动添加,允许一个事务去读一行,其他事务可以读数据,但不能修改数据。

SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE -- 共享读锁 手动添加

排他写锁(X):自动添加,指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁

InnoDB也实现了表级锁,也就是意向锁,意向锁是mysql内部使用的,不需要用户干预。

两阶段锁(2PL)

两阶段锁讲的是锁操作分为两个阶段:加锁阶段和解锁阶段。

加锁阶段:只加锁,不放锁。

解锁阶段:只放锁,不加锁。

行锁演示

InnoDB行锁是通过给索引上的索引项加锁来实现的,因此只有通过索引条件检索的数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!

行读锁

1、我们利用session1给id=1的行加读锁,使用索引。

session1: begin;
          select * from mylock where ID=1 lock in share mode; 

精通MySQL之锁篇

2、由于行锁锁定的是行,所以利用session2修改别的行例如id=2是可以的,修改id=1就不行了。

session2:update mylock set name='M' where id=2;
session2:update mylock set name='M' where id=1;

精通MySQL之锁篇

3、当session1提交后,session2才可以修改。

session1: commit; 
session2:update mylock set name='M' where id=1; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

精通MySQL之锁篇

关于行锁,我们要注意使用索引加行锁 ,未锁定的行可以访问。

行读锁升级为表锁

mylock表中id加了索引,name没有加索引,当我们对name加行读锁时,就会出现行读锁升级为表锁。

1、session1开启事务

session1: begin;

2、手动加name='c'的行读锁,未使用索引

select * from mylock where name='c' lock in share mode;

3、session2修改阻塞,未用索引行锁升级为表锁

update mylock set name='N' where id=2;

4、session1提交事务或者 rollback 释放读锁

commit;

5、session2就会修改成功

update mylock set name='N' where id=2;

行写锁

1、session1开启事务并且手动加id=1的行写锁。

session1: begin;
          select * from mylock where id=1 for update;

2、这里有一个特别重要的知识点,很多人会弄错!

排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的!

排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。MySQL InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以其他事务是不能修改加过排他锁的数据行,其他事务也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

所以session2可以访问id=1的数据行。

session2: select * from mylock where id=1 ;

3、但是不能给它继续加锁

session2: select * from mylock where id=1 lock in share mode ;

精通MySQL之锁篇

4、session1提交事务或者rollback释放写锁,session2才会执行成功

精通MySQL之锁篇

间隙锁

精通MySQL之锁篇

根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。根据图中where number=5的话,那么间隙锁的区间范围为(4,11);

间隙锁防止两种情况

防止插入间隙内的数据

防止已有数据更新为间隙内的数据

间隙情况:

id、number均在间隙内

id、number均在间隙外

id在间隙内、number在间隙外

id在间隙外,number在间隙内

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdgxy.html