云端之上 發表於 2026-1-10 11:21:15

MySQL数据库意向锁超级入门篇

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、为什么需要意向锁?</a></li><li><a href="#_label1">二、意向锁的类型</a></li><li><a href="#_label2">三、意向锁的工作机制</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">1️⃣ 加行锁前,先加意向锁(表级)</a></li><li><a href="#_lab2_2_1">2️⃣ 锁兼容关系(重点)</a></li></ul><li><a href="#_label3">四、举例说明(非常重要)</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_2">示例 1:行锁 + 意向锁</a></li><li><a href="#_lab2_3_3">示例 2:表锁检测冲突</a></li></ul><li><a href="#_label4">五、意向锁的特点总结</a></li><ul class="second_class_ul"></ul><li><a href="#_label5">六、一句话总结</a></li><ul class="second_class_ul"></ul></ul></div><p>在 <strong>MySQL(主要是 InnoDB 存储引擎)</strong> 中,<strong>意向锁(Intention Lock)</strong> 是一种 <strong>表级锁</strong>,用来表示<strong>事务打算在表中的某些行上加什么类型的行锁</strong>,从而<strong>提高锁冲突判断的效率</strong>。</p>
<p class="maodian"><a name="_label0"></a></p><h2>一、为什么需要意向锁?</h2>
<p>InnoDB 同时支持:</p>
<ul><li><strong>表锁</strong></li><li><strong>行锁</strong></li></ul>
<p>如果没有意向锁,当一个事务想给整张表加锁时,就必须 <strong>逐行检查是否有行锁存在</strong>,这在大表中会非常低效。</p>
<p>👉 <strong>意向锁的作用</strong>:<br />让数据库 <strong>只需检查表级的意向锁,就能快速判断是否可以加表锁</strong>,而不必扫描整张表的行锁。</p>
<p class="maodian"><a name="_label1"></a></p><h2>二、意向锁的类型</h2>
<p>InnoDB 有 <strong>两种意向锁</strong>:</p>
<table><thead><tr><th>意向锁类型</th><th>含义</th></tr></thead><tbody><tr><td><strong>IS(Intention Shared Lock)</strong></td><td>表示事务打算在表中某些行上加 <strong>共享锁(S)</strong></td></tr><tr><td><strong>IX(Intention Exclusive Lock)</strong></td><td>表示事务打算在表中某些行上加 <strong>排他锁(X)</strong></td></tr></tbody></table>
<p class="maodian"><a name="_label2"></a></p><h2>三、意向锁的工作机制</h2>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>1️⃣ 加行锁前,先加意向锁(表级)</h3>
<p><strong>加行级共享锁(S)前</strong><br />&rarr; 先在表上加 <strong>IS 锁</strong></p>
<p><strong>加行级排他锁(X)前</strong><br />&rarr; 先在表上加 <strong>IX 锁</strong></p>
<blockquote><p>⚠️ 意向锁 <strong>不是用户显式加的</strong>,而是 InnoDB <strong>自动维护的</strong></p></blockquote>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>2️⃣ 锁兼容关系(重点)</h3>
<table><thead><tr><th></th><th>IS</th><th>IX</th><th>S</th><th>X</th></tr></thead><tbody><tr><td><strong>IS</strong></td><td>✔</td><td>✔</td><td>✔</td><td>✘</td></tr><tr><td><strong>IX</strong></td><td>✔</td><td>✔</td><td>✘</td><td>✘</td></tr><tr><td><strong>S</strong></td><td>✔</td><td>✘</td><td>✔</td><td>✘</td></tr><tr><td><strong>X</strong></td><td>✘</td><td>✘</td><td>✘</td><td>✘</td></tr></tbody></table>
<p>📌 关键理解:</p>
<ul><li><strong>多个事务可以同时持有 IS / IX</strong></li><li><strong>表级 S / X 锁会与意向锁发生冲突</strong></li><li><strong>意向锁之间几乎不冲突</strong></li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>四、举例说明(非常重要)</h2>
<p class="maodian"><a name="_lab2_3_2"></a></p><h3>示例 1:行锁 + 意向锁</h3>
<div class="jb51code"><pre class="brush:sql;">START TRANSACTION;
SELECT * FROM user WHERE id = 1 FOR UPDATE;
</pre></div>
<p>发生的事情:</p>
<ol><li>在 <code>user</code> 表上加 <strong>IX(意向排他锁)</strong></li><li>在 <code>id = 1</code> 这行上加 <strong>X(排他锁)</strong></li></ol>
<p class="maodian"><a name="_lab2_3_3"></a></p><h3>示例 2:表锁检测冲突</h3>
<div class="jb51code"><pre class="brush:sql;">LOCK TABLE user WRITE;
</pre></div>
<p>MySQL 只需检查:</p>
<ul><li><code>user</code> 表上是否存在 <strong>IS / IX</strong></li></ul>
<p>如果存在 <strong>IX</strong>,说明有事务在改某些行<br />➡️ <strong>WRITE 表锁不能加,直接阻塞或失败</strong></p>
<p class="maodian"><a name="_label4"></a></p><h2>五、意向锁的特点总结</h2>
<p>✅ 意向锁是 <strong>表级锁</strong><br />✅ 由 InnoDB <strong>自动加锁与释放</strong><br />✅ 不会阻塞 <strong>行锁之间的并发</strong><br />✅ 用于 <strong>快速判断表锁与行锁是否冲突</strong><br />✅ 是 <strong>多粒度锁(Multi-Granularity Locking)</strong> 的核心机制</p>
<p class="maodian"><a name="_label5"></a></p><h2>六、一句话总结</h2>
<blockquote><p><strong>意向锁是 InnoDB 的一种表级锁,用来表明事务将要在表的某些行上加行锁,从而避免在加表锁时逐行检查行锁,提高锁冲突检测的效率。</strong></p></blockquote>
<p>推荐阅读《<a href="https://www.jb51.net/database/3565248s8.htm" target="_blank">MySQL 数据库 意向锁 详解(白话篇:一看就懂)</a>》</p>
頁: [1]
查看完整版本: MySQL数据库意向锁超级入门篇