共享锁(读锁)
读锁:也称为共享锁、英文用S表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。
<span style="color: rgb(16, 18, 20); font-family: "PingFang SC", "Segoe UI", Arial, "Microsoft YaHei", 微软雅黑, 宋体, "Malgun Gothic", sans-serif; font-size: 14px; white-space: pre-wrap; caret-color: rgb(251, 74, 62);">在采用加锁方式解决</span><span style="font-family: "PingFang SC", "Segoe UI", Arial, "Microsoft YaHei", 微软雅黑, 宋体, "Malgun Gothic", sans-serif; font-size: 14px; white-space: pre-wrap; caret-color: rgb(251, 74, 62);"><font color="#e57373">脏读、不可重复读、幻读</font></span><span style="color: rgb(16, 18, 20); font-family: "PingFang SC", "Segoe UI", Arial, "Microsoft YaHei", 微软雅黑, 宋体, "Malgun Gothic", sans-serif; font-size: 14px; white-space: pre-wrap; caret-color: rgb(251, 74, 62);">这些问题时,读取一条记录时需要获取该记录的S锁,其实是不严谨的,有时候需要在读取记录时就获取记录的X锁,来禁止别的事务读写该记录,</span><br>
查询时获取读锁的两种方式
SELECT ... LOCK IN SHARE MODE<br>
SELECT ... FOR SHARE<br>
MySQL8.0新特性
在SELECT ... FOR UPDATE 后可以添加关键字,<br>用于控制没有获取到锁时的行为
SKIP LOCKED
立即返回,只是返回的结果中不包含被锁定的行
排他锁(写锁)<br>
写锁:也称为排他锁、英文用x表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。
修改时获取写锁的方式
UPDATE ... FOR UPDATE
S锁和X锁兼容性
写操作
DELETE
对一条记录做DELETE操作的过程其实是先在B+树中定位到这条记录的位置,然后获取这条记录的X锁,再进行delete mark操作。<br>我们也可以把这个定位待删除记录在B+树中位置的过程看成是一个获取X锁的锁定读。
UPDATE
情况1:未修改该记录的键值,并且被更新的列占用的存储空间在修改前后未发生变化。
情况2:未修改该记录的键值,并且至少有一个被更新的列占用的存储空间在修改前后发生变化。
情况3:修改了该记录的键值<br>
INSERT
一般情况下,新插入一条记录的操作并不加锁,通过一种称之为<font color="#f44336">隐式锁</font>的结构来保护这条新插入的记录在本事务提交前不被别的事务访问。