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

推薦する

シンプルなカルーセル効果を実現するネイティブ js

この記事では、シンプルなカルーセル効果を実現するためのjsの具体的なコードを参考までに紹介します。具...

Vueのログインとログアウトの詳細な説明

目次ログインビジネスプロセスログイン機能の実装要約するまず、エフェクトの実装プロセスを見てみましょう...

キャンバスはスクラッチカード効果を描画します

この記事では、キャンバスでスクラッチカード効果を描画するための具体的なコードを参考までに共有します。...

Dockerはbusyboxを使用してベースイメージを作成します

Docker イメージの最初の行は FROM alpine などのイメージで始まりますが、最初のベー...

Centos7 に mysql 8.0.13 (rpm) をインストールする詳細なチュートリアル

yum か rpm か? yum によるインストール方法は非常に便利ですが、公式サイトから MySQ...

コードブロックのハイライトをコピーして表示できる js プラグイン highlight.js + clipboard.js 統合

主に2つの側面から: 1. ハイライト/改行2. コードのコピーボタンこれら両方には既製のプラグイン...

Ubuntu 18仮想マシンのクローン作成後に同じIPアドレスになる問題の解決方法

序文最近、仮想マシンを使用して Ubuntu 18.04 をインストールしました。クローン作成後、I...

XHTML 入門チュートリアル: XHTML Web ページ画像アプリケーション

<br />適度に画像を追加すると、Web ページがより美しくなります。 画像タグ &l...

Dockerコンテナの紹介

1. 概要1.1 基本概念: Docker は、Go 言語をベースにしたオープンソースのアプリケーシ...

Zabbix ベースの Jenkins プロセス監視の詳細な説明

1. 監視アーキテクチャ図 2. 実装のアイデアJenkins に Metrics プラグインをイン...

MYSQL 左結合の最適化 (10 秒から 20 ミリ秒)

目次【機能背景】 [生のSQL] 【独自SQL解析】 【分析手順】 [最適化されたSQL] 【最適化...

Linuxでバージョン情報を表示する方法

Linux でバージョン情報を表示する方法。ビット数、バージョン情報、CPU コア情報、CPU 固有...

DockerイントラネットはDNSを構築し、ip:port操作の代わりにドメイン名アクセスを使用します

たとえば、イントラネットに Jenkins サーバーがある場合、そのサーバーにアクセスするには、その...

ウィンドウ環境で VScode を使用して仮想マシン MySQL に接続する方法

1. 仮想マシン側1. MySQLの設定ファイルを見つける:sudo vim /etc/mysql/...

MySQLでインデックスエラーが発生する状況について簡単に説明します

以下に、トレーニング機関からのヒントと私自身の要約をいくつか示します。以下のインデックスの内容を説明...