ホームページ > データベース > mysql チュートリアル > MySQL および InnoDB での共有ロックと排他ロックを説明する例

MySQL および InnoDB での共有ロックと排他ロックを説明する例

WBOY
リリース: 2022-02-08 18:00:29
転載
2386 人が閲覧しました

この記事では、mysql の共有ロックと排他的ロックに関する関連知識を提供します。皆様のお役に立てれば幸いです。

MySQL および InnoDB での共有ロックと排他ロックを説明する例

共有ロック

共有ロック、S ロック、読み取りロック はすべて彼のものです名前。

そして、私は彼を 共有読み取りロック と呼びたいと思います。

#共有 (S) ロックでは、ロックを保持しているトランザクションによる読み取りが許可されます。

#共有ロックを使用すると、ロックを保持しているトランザクションが読み取りを行うことができます。

ここでの共有とは、

読んで共有する です。

つまり、行レベルであろうとテーブルレベルであろうと、特定のデータに共有読み取りロックが設定されている場合、

他のトランザクションは読み取りを続行できます(つまり、共有読み取りロック)保持することは許可されています)が、書き込むことはできません。つまり、読み取りと書き込みは相互に排他的です。 ところで、共有ロック (共有読み取りロック) を追加する方法を紹介します。

上位のテーブルレベルの共有ロック、つまりテーブルレベルの共有読み取りロック:

select  *  from table(表) lock in share mode ;
ログイン後にコピー

アップストリーム レベルの共有ロック、つまり行レベルの共有読み取りロック:

select  *  from table(表)where id = 10  
lock in share mode
 ;
ログイン後にコピー

ここでもう少し詳しく説明します。InnoDB では、次の場合に行ロックを使用するだけではないことに注意してください。行ロックを使用したい場合は、行ロックのトリガー条件をもう一度確認してみましょう (冒頭で説明しました):

排他ロック

排他ロック、書き込みロック、X ロックはすべて彼の名前です。

そして私は彼を

排他的書き込みロック

と呼びたいと思います。

排他的 (X) ロックは、ロックを保持しているトランザクションに更新または削除を許可します。

排他的 (X) ロックを使用すると、ロックを保持しているトランザクションが更新または削除できます。

独占、この言葉。バスケットボールをしたことがありますか? 私は中学校の時はバスケットボールのやり方を知らなかったので、ボールを持ったままパスをすることはできませんでした。クラスメートは私に、あなたはとても孤独だと言いました。

はい、私はとても孤独です。この排他的書き込みロック(排他ロック)と同様に、非常にユニークです。


トランザクションが特定のデータに排他的書き込みロック (排他的ロック) を追加すると、現在のトランザクションのみがデータを変更または削除できます。

#他のトランザクションは読み取りまたは書き込みできません

。このロックは非常に一意であるため、他のトランザクションがこのロックを利用できるようになる前に、この非常に一意のロックが使い果たされる (解放される) まで待つ必要があります。 したがって、排他的書き込みロック (排他ロック) は 読み取りと書き込みでは相互に排他的であり、書き込みと書き込みでは相互排他的です

ところで、排他ロック(排他書き込みロック)の追加方法を紹介します: 上位のテーブルレベルの排他ロック、つまりテーブルレベルの排他書き込みロック:

select * from table
 for update 
;
ログイン後にコピー

アップストリーム レベルの排他的ロック、つまり行レベルの排他的書き込みロック:

select * from table where id =10 
 for update
 ;
ログイン後にコピー

ここでもう少し詳しく説明します。InnoDB では行ロックを使用するだけではないことに注意してください。行ロックを使用したい場合は、行ロック条件を再度トリガーします。確認するには (冒頭で説明した):

上記の SQL は上流レベルを達成できます。インデックスにヒットするため、排他ロックが発生し、id がインデックスになります。

これを見ても、共有ロックと排他ロックについてまだ漠然としているかもしれませんが、読み取りと読み取りの共有、読み取りと書き込みの相互排他、書き込みと書き込みの相互排他などについてはおおよそ理解できます。

したがって、これら 2 つのロックを神の観点からもう一度見る必要があります。

Red

トランザクション操作 1

トランザクション操作 2

はい、互換性があります。一緒にお読みください排他ロック (排他書き込みロック)いいえ、互換性がありません。排他ロックが設定されている場合、他のものは何もできません。移動
#共有ロック (共有読み取りロック)
#排他ロック (排他書き込みロック) 共有ロック (共有読み取りロック)
いいえ、互換性がありません。希望する場合は待つ必要があります。 write 共有ロックがなくなりました
移動できません、互換性がありません、排他的にロックされており、他の人は移動できません

那么如果你看到这里,还是对 共享锁 & 排他锁还只是云里雾里。

那我只有动手了!

实战介绍,演示 所谓的读读共享、读写互斥、写写互斥 。

在演示读读共享、读写互斥、写写互斥前, 我必须点明一点!

在这篇文章里面,我介绍了一些上 共享锁(共享读锁)、排他锁(独占写锁)的方式 。 但是 可以看到写的查询sql 都是后面加了东西的 , lock in share mode ,for update .... 等。

所以我想点明的一点是,

如果是使用 普通的查询 ,是 什么锁都没上的!

就好像平时我们经常写的

select * from table ;
select * from table where age=18;

select语句默认不会加任何锁类型

select语句默认不会加任何锁类型

select语句默认不会加任何锁类型

而排他锁,除了 select .... for update ,InnoDB引擎 默认的修改 、插入、删除(update,insert,delete)都是会给操作的相关数据 加 排他锁的 .

废话不多说,我们上才艺:

准备一些用于测试的数据。

建表:

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `sex` tinyint(1) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
ログイン後にコピー

搞点模拟数据:


(id主键索引)

第一个小实践:

我们不废话,我们直接上共享读锁, 看看是不是能 符合刚才我们的理论 读读共享,读写互斥

1. 我们先给id=3这数据上个 共享读锁:

2.基于当前状况, 我们再执行一下查询语句,也是使用共享读锁的:

3.那么也是基于当前情况,我们再执行一下使用排他写锁的查询语句,可以发现 读写互斥了:

4.验证下,我们查看当前是否存在事务在等待锁:

可以从结果中看出 事务请求id 34847在等待锁:

我们再查询一下,那些事务在使用锁,
可以从结果看出,34844事务在使用S锁,也就是共享读锁;

而34847事务 在使用 X锁, 也就是排他写锁(但是由于共享读锁先上了,所以读写互斥了),所以造成了34847事务 在等待锁。

5.那么如果我们一直不 COMMIT 共享读锁, 34847事务 会永无止息地等待锁吗?   那么肯定是不可能允许这种一直等待的场景的:

所以mysql会有个等待锁资源超时的机制,这种情况就会直接返回查询失败的结果。

根据第一个小实践,我们得出一个很明显的结论:

当某数据上了 共享读锁 S 时, 只允许其他事务上共享读锁 S, 因为读读共享;

不允许其他事务上 独占写锁 X(除非把这个共享读锁S 释放掉),因为读写互斥。

第二个小实践:

1.我们直接给某行数据上个排他写锁 X (注意我们的事务是没有执行COMMIT的) :

2. 我们接下来去 通过共享读锁去获取数据,看看会发生什么?

这就是 独占写锁 X 的 读写互斥、写写互斥 (写写互斥的场景就不展示了).

再验证下,我们看下是不是存在事务在等待锁资源:

3. では、排他的書き込みロックが解放されない場合、他のトランザクションは待ち続けるのでしょうか?

同じことが当てはまり、タイムアウトになってクエリの失敗が返されるまで待機します:

少し練習を追加します:

1.同じ、最初に特定のデータをアップロードします 排他的書き込みロック、COMMIT なし:

2. 通常のクエリを実行、選択:

ご覧のとおり、通常の select ステートメントは正常に取得できますが、なぜでしょうか。

そこで、もう一度詳しく説明する必要がありますが、いわゆる読み取り-読み取り共有、読み取り-書き込み相互排他、および書き込み-書き込み相互排他は次のとおりです。とはいえ、ロック リソースをめぐって競合しないのであれば、相互排他や相互排他は存在しないはずです。

推奨学習: mysql ビデオ チュートリアル

以上がMySQL および InnoDB での共有ロックと排他ロックを説明する例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート