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ではボタンが両側に伸びる

推薦する

VMware仮想マシンにLinux(CentOS)をインストールするための詳細な構成手順

CentOS7をダウンロード私がダウンロードしたイメージはCentOS-7-x86_64-DVD-1...

Nginx は gzip 圧縮に基づいてアクセス速度を向上します

1. nginx はなぜ gzip を使用するのですか? 1. 圧縮の役割:ページがgzipで圧縮さ...

MySQL データベースの最適化: テーブルとデータベースのシャーディング操作の詳細な説明

この記事では、例を使用して、MySQL データベースの最適化のためのテーブルおよびデータベース シャ...

Vue2は応答性を提供するためにprovide injectを実装しています

1. vue2 での従来の書き方 // 親コンポーネントは 'foo' を提供します...

Nginx 仮想ホストの詳細な分析

目次1. 仮想ホスト1.1 仮想ホストの概念1.2 仮想ホストタイプ2. IP仮想ホストに基づく2....

Docker Compose を使用して ELK を迅速にデプロイする (テスト済みで効果的)

目次1. 概要1.1 定義1.2 機能説明2. ELKを展開する2.1 ディレクトリとファイルを作成...

Vue+js はビデオのフェードインとフェードアウト効果を実現します

Vue+jsはビデオのフェードインとフェードアウトを実現します。参考までに、具体的な内容は次のとおり...

Vue2.0の双方向データバインディング原則を手動で実装する

一言で言えば: データハイジャック (Object.defineProperty) + パブリッシュ...

MySQL 8.0.13 のダウンロードとインストールのチュートリアル(画像とテキスト付き)

MySQL は最もよく使用されるデータベースです。詳しく知るには、コンピュータにインストールする必...

Vue でルートをジャンプする方法をご存知ですか?

目次最初の方法: router-link (宣言型ルーティング) 2番目の方法: router.pu...

JavaScript での AOP プログラミングの基本実装

AOP の紹介AOP (アスペクト指向プログラミング) の主な機能は、コアビジネスロジックモジュール...

HTMLポップアップdivはモバイルの中央揃えを実現するのに非常に便利です

コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBLIC "...

Linuxのbasenameコマンドの使い方

01. コマンドの概要basename - ファイル名からディレクトリとサフィックスを削除しますba...

NavicatがLinuxサーバー上のMySQLに接続できない問題を解決する

最初は悲しい気持ちになりました。スクリーンショットは以下の通りです。 少し苦労しましたが、解決策は次...

純粋な CSS 流星群の背景サンプルコード

GitHubアドレス、気に入ったらスターを付けてくださいプラグインのプレビューチュートリアルコード表...