MySQL中的锁还是蛮多的。上一篇宋兄介绍了MySQL中的MDL锁(为什么执行alter更新表时需要谨慎?),今天我们就来看看MySQL中比较重要的几个。两种锁:S锁和X锁。1、S锁S锁,英文是SharedLock,中文翻译是共享锁,有时我们也称它为读锁,即ReadLock。S锁是共享的,或非阻塞的。当一个事务读取一条记录时,需要先获取该记录的S锁。例如:事务T1给记录R1加了S锁,那么事务T1可以读取R1的行,但是不能修改R1,其他事务T2可以继续给R1加S锁,但是不能加X锁,只有当S在可以添加X锁之前释放R1上的锁。以加S锁为例,如下图所示:此时对于id=1的记录,只能读不能修改。假设在另一个事务T中,执行如下SQL没有问题,因为S锁是共享锁,S锁和S锁是兼容的:select*fromuserwhereid=1lockinsharemode;但是如果执行下面的SQL会被阻塞,因为修改数据需要获取X锁,而S锁和X锁不兼容:updateusersetusername='javaboy'whereid=1;上面的update语句内部会获取X锁,对于一些手动加了X锁的Query语句也会阻塞,比如下面的:可以看到,SQL执行完就阻塞了。2.X锁X锁,英文是ExclusiveLock,中文翻译是独占锁,有时我们也称它为写锁,即WriteLock。X锁就像它的名字一样是排他的,即一个写锁会阻塞其他的X锁和S锁。当事务需要修改一条记录时,需要先获取该记录的X锁。例如:事务T1给记录R1加了一个X锁,那么事务T1就可以读取R1并修改R1,而其他事务不能给R1加任何锁,直到T1释放对R1的锁。如上图,lockedread的格式如下:select....forupdate;3、currentread和snapshotread由上面的两种锁,衍生出两种read:3.1SnapshotreadSnapshotread(SnapShotRead)是不带锁的一致性读,这也是InnoDB存储的核心原因之一引擎有这么高的并发。在repeatableread的隔离级别下,当事务开始时,会为当前库拍摄一张照片(快照),快照读取的数据要么是拍摄照片时的数据,即库中的数据事务开始时的数据库,或者当前事务本身插入/修改的数据。我们日常使用的解锁查询都是快照读,这里就不演示了。3.2当前读对应快照读。当前读取是读取最新的数据,不是数据的历史版本。也就是说,在可重复读隔离级别下,如果当前读被使用,其他读也可以被读到。事务提交的数据。松哥举了个例子:MySQL事务开启了两个sessionA和B,首先在sessionA中开启一个事务,查询id为1的记录:接下来我们修改sessionB中id为1的数据,如下:注意sessionB不应开启事务或启用及时提交事务,否则update语句会占用排他锁,导致会话A在使用锁时阻塞。接下来回到sessionA继续查询操作,如下:可以看到,sessionA中的第一个查询是snapshotread,读取的是当前事务启动时的数据状态,接下来的两个查询是currentRead,读取最新的数据(sessionB中修改的数据)。4.总结的不错,小知识点,日积月累,加油!
