MySQL ロック制御同時実行方法

MySQL ロック制御同時実行方法

序文

ロックは一般的に、楽観的ロックと悲観的ロックに分けられます。簡単に言うと、楽観的ロックはバージョン番号によって制御され、悲観的ロックはロックによって制御されます。

以下はテストに使用するデータです

# ユーザーテーブルを追加する CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
 `name` varchar(255) NOT NULL COMMENT '名前',
 主キー (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 デフォルト CHARSET=utf8;
#3つのレコードを挿入 INSERT INTO `users` (`id`, `name`)
価値観
 (1、「雪山飛豚」)
 (2、「陳瓊河」)、
 (3、 'cqh');

クエリ結果は次のとおりです。

1. 楽観的ロック

基本原則は、制御用のバージョン フィールドを追加することです。
たとえば、1つの行を同時に更新したい場合、次のように1つのプロセスのみが正常に更新されます。

UPDATE users SET name="雪山飞猪" WHERE id=3
ユーザーを更新します。SET name="chenqionghe" WHERE id=3

上記の 2 つの SQL ステートメントは最終的に正常に更新され、最後の更新結果がメインのものになります。

解決策はバージョンフィールドを追加することです

バージョンフィールドを追加する

ALTER TABLE users ADD `version` INT NOT NULL DEFAULT '0'

解決策は、バージョンフィールドを追加し、それを各更新のwhere条件に追加し、更新することです。

ユーザーを更新します。SET name="雪山飞猪",version=version+1 WHERE id=3 AND version=0
ユーザーを更新します。SET name="chenqionghe",version=version+1 WHERE id=3 AND version=0

今回は、更新は 1 回だけ成功し、最初にレコードを取得した人がマスターになります。これは、現在のプロセスが正常に更新された後にバージョン番号が変更され、2 番目のプロセスがこのレコードを見つけることができないためです。
これは最も単純な CAS メカニズムです。

2. 悲観的ロック

実際、これはGo言語のMutexとRwMutexの読み取りロックに似ています。

読み取りロック

共有ロックまたは S ロックとも呼ばれる共有ロックがデータ テーブルに追加されると、テーブルは読み取り専用モードになります。
次のようにテーブル全体をロックすることも、テーブル全体または一部の行をロックすることもできます。

完全なテーブルロック (LOCK TABLE table READ)

構文は次の通りです

LOCK TABLE テーブル読み取り
テーブルのロックを解除します。

1つテストしてみましょう。最初のプロセスは実行されます

LOCK TABLE ユーザーは読み取ります。 

2番目のプロセスは通常の読み取りを実行する

SELECT * FROM users WHERE id=1; 

通常通りクエリを実行できます。もう一度アップデートしてみましょう

ユーザーを更新します。SET name="chenqionghe" WHERE id=1 

待ち時間がありました。

最初のプロセスのロックを解除します

2番目のプロセスを見ると、正常に更新されています

行ロック (SELECT ... LOCK IN SHARE MODE)

始める;
SELECT * FROM users WHERE id IN (1,2) LOCK IN SHARE MODE
専念;

トランザクションで使用する必要があります。BEIN の開始後、ロックされた行は外部からのみクエリ可能であり、更新することはできません。

テストしてみましょう。最初のプロセスは

始める;
SELECT * FROM users WHERE id IN (1,2) LOCK IN SHARE MODE 

ここでは、ID 1 と 2 の行がロックされています。 2番目のプロセスは更新を実行します

UPDATE users SET name="雪山飞猪" WHERE id=1

またしても待ち時間が発生しました。
さて、最初のプロセスのトランザクションをコミットします

専念; 

2回目のプロセス更新は次のように成功しました。

書き込みロック

排他ロック、排他ロックは読み取りと書き込みが不可能であると理解され、構文は次のとおりです。

完全なテーブルロック (LOCK TABLE table WRITE)

LOCK TABLE ユーザーは書き込みます。

この時点で、テーブル全体がロックされています。別のプロセスを使用して、ID 1 のデータをクエリしてみましょう。

SELECT * FROM users WHERE id=1 

ご覧のとおり、クエリはすでに待機中です。
最初のプロセスのロックを解除しましょう。

テーブルのロックを解除

この時点で、2番目のプロセスはすぐにクエリに成功します。

行ロック (SELECT ... FOR UPDATE)

データを更新すると (INSERT、DELETE、UPDATE)、データベースは自動的に排他ロックを使用して、他のトランザクションがデータを操作できないようにします。

始める;
SELECT * FROM users WHERE id IN (1,2) LOCK IN SHARE MODE
専念;

もう一度テストしてみましょう。最初のプロセスは、ID 1 と 2 のレコードをロックします。

始める;
SELECT * FROM users WHERE id IN (1,2) FOR UPDATE

注: この時点ではトランザクションはコミットされていません

まず、2番目のプロセスを使用して、ID 3(ロックされていない)のレコードを更新します。

ユーザーを更新します。SET name="chenqionghe" WHERE id=3 

実行は成功しました。
ID 1 のレコードを更新してみましょう。

ユーザーを更新します。SET name="chenqionghe" WHERE id=1

待機が発生し、ロックされたことを示します。
さて、最初のプロセスのトランザクションを送信しましょう

専念;

2番目のプロセスをもう一度見てください。正常に更新されています。

簡単に言うと、楽観的ロックはバージョン管理を使用し、悲観的テーブル ロックは通常は必要なく、行読み取りロックは LOCK IN SHARE MODE を使用し、書き込みロックは FRO UPDATE を使用します。とても簡単です。

上記は、MySQL のロックと同時実行の制御方法の詳細です。MySQL のロックと同時実行の制御の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL でテーブル メタデータ ロックを待機する理由と方法
  • MySQLのテーブル構造を変更する際に知っておきたいメタデータロックの詳しい解説
  • MYSQL メタデータ ロック (MDL ロック) MDL ロックの問題分析
  • MySQLスレーブは列の外部キーチェックと自動増分ロックを遅延します
  • MySQLのネクストキーロックのロック範囲についての簡単な説明
  • PHP+MySQL の高同時ロックトランザクション処理問題の解決方法
  • MYSQL メタデータ ロック (MDL ロック) の理論とロック タイプ テスト

<<:  Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明

>>:  IEではボタンが両側に伸びる

推薦する

MySql でリモート接続を許可する方法

MySql でリモート接続を許可する方法この目標を達成するには、2つのことを行う必要がある。ユーザー...

Vue で webSocket を使用してリアルタイムの天気を更新する方法

目次序文webSocket の操作と例について:ウェブソケット1. webSocketについて2. ...

MySQL で乱数を生成し、文字列を連結する方法の例

この記事では、MySQL が乱数を生成し、文字列を連結する方法について例を使用して説明します。ご参考...

HTML、CSS、JSコメントの標準的な使用法の概要

必要なコメントを追加することは、責任感と道徳心のあるフロントエンド開発者が持つべき良い習慣であり、コ...

Mybatisの各SQL文の実行時間の統計

背景最近、面接でデータベース トランザクションについてよく質問されます。通常は、@Transacti...

Dockerで最もよく使われるイメージコマンドとコンテナコマンドの詳細な説明

この記事では、Docker の使用で最もよく使用されるイメージ コマンドとコンテナ コマンドを一覧表...

FTP、FTPS、SFTPの違いについて簡単に説明します

目次FTP、FTPS、SFTP の概要FTP FTPS FTPサーバーFTPソフトウェアのアクティブ...

Linux でディスク IO を表示し、読み取りと書き込みで高い IO を占有するプロセスを見つけます。

背景 - オンラインアラートオンライン サーバーがアラームを発し、ディスク使用率 disk.util...

MySQLデータベース最適化技術の簡単な紹介

成熟したデータベース アーキテクチャは、最初から高可用性、高スケーラビリティなどの機能を備えて設計さ...

JavaScript で DOM 要素を監視する MutationObServer の詳細

1. 基本的な使い方これは MutationObserver コンストラクターを通じてインスタンス化...

Vue 日付時刻ピッカーコンポーネントの使い方の詳細な説明

この記事の例では、Vue の日付時刻ピッカーコンポーネントの具体的なコードを参考までに紹介します。具...

JavaScript の一般的なステートメント ループ、判定、文字列から数値

目次1. スイッチ2. whileループ3. Do/Whileループ3. 文字列を数値に変換する1....

MySQL の冗長インデックスと重複インデックスの詳細な説明

MySQL では、同じ列に複数のインデックスを作成できます。意図的であるかどうかにかかわらず、MyS...

HTML、CSS、RSSフィードが正しいかどうかを確認する無料ツール

この種のエラーに対処するための 1 つの方法は、まずマークアップとスタイルシートを検証することです。...