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 ルートパスワードをリセットする方法

目次1. ルートパスワードを忘れてしまい、データベースにアクセスできない: DBA にとって、スーパ...

Vue ターンテーブル抽選の簡単な実装

この記事では、ホイール抽選を簡単に実装するためのVueの具体的なコードを参考までに共有します。具体的...

理論の普及——ユーザーエクスペリエンス

1. 概念分析 1: UE ユーザー エクスペリエンス <br />英語ではユーザー エ...

Linux でのマルチスレッドプログラミング例の分析

1 はじめにスレッド技術は 1960 年代にすでに提案されていましたが、マルチスレッドがオペレーティ...

Reactにおけるフックの一般的な使用法

目次1. フックとは何ですか? 2. フックはなぜ現れるのでしょうか? 3. よく使われるフックは何...

Linuxでシンボリックリンクを削除(削除)するコマンド

Linux では、シンボリック リンクを作成または削除する必要がある場合があります。もしそうなら、何...

制限およびオフセット ページング シナリオを使用すると速度が遅くなるのはなぜですか?

質問から始めましょう5 年前、私が Tencent にいたとき、ページング シナリオでは MySQL...

Linux (CentOS) システムで MySQL データベース ディレクトリの場所を変更する方法

CentOS システムで MySQL データベース ディレクトリの場所を変更する方法1. まず、My...

ウェブページのコピー防止機能の実装方法(クラッキング手法付き)

ソース ファイルを右クリックすると、次のコードが見つかります。 1. CSSを使用してFirefox...

CSS BEM 命名標準の概要 (推奨)

1 BEM命名標準とはBem は、ブロック、要素、修飾子の略語であり、Yandex チームによって...

Vue で手ぶれ補正を実装するためのサンプルコード

手ぶれ防止: 繰り返しのクリックによるイベントのトリガーを防止まず、揺れとは何でしょうか? 震えるの...

Linux を使用して時間指定ファイルが占有するディスク容量を計算する方法

スケジュールされたタスク エディターを開きます。Cent は、デフォルトで vim を使用して直接開...

Mariadb リモート ログイン構成と問題解決

序文:インストール プロセスについては詳しく説明しません。問題に直接触れましょう。MySQL のリモ...

@font-face を使用して Web ページに特殊文字を実装する (カスタム フォントを作成する)

数日前、CSS を使用して三角形の矢印を実装する方法について記事を書きました。 目的の効果は達成され...

MySQL 8.0.12 winx64 解凍バージョンのインストール グラフィック チュートリアル

mysql-8.0.12-winx64 解凍版のインストールを記録して、みんなで共有しました。 1....