MySQLデータの同時更新を処理する方法

MySQLデータの同時更新を処理する方法

UPDATE はロックしますか?

以下のような場合、SQL文はロックされますか?

テーブル1を更新します。SET num = num + 1 WHERE id=1;

答えはノーだ

実際、MySQL はデータ行のロック (InnoDB) をサポートしており、UPDATE/DELETE 操作中に排他ロックを自動的に追加します。ただし、 UPDATE キーワードがある限り、すべてのロックが適用されるわけではありません。 上記の MySQL ステートメントの場合、1 つの UPDATE ステートメントではなく、2 つの SQL ステートメント (疑似コード) に類似している必要があります。

a = SELECT * FROM table1 WHERE id=1;
テーブル1を更新します。SET num = a.num + 1 WHERE id=1;

SELECT ステートメントを実行するときにはロックはなく、UPDATE を実行するときにのみロックされます。そのため、同時操作中に更新データの不整合が発生します。原因が見つかれば、問題の解決はそう遠くありません。この種の問題を解決するには 2 つの方法があります。

  • トランザクションを通じてSELECTを明示的にロックする
  • 楽観的ロック機構を使用する

明示的に選択する

SELECT をロックする方法は次の 2 つあります。

SELECT ... LOCK IN SHARE MODE #共有ロック、他のトランザクションは読み取り可能だが更新不可 SELECT ... FOR UPDATE #排他ロック、他のトランザクションは読み取りも書き込みも不可

これら 2 つのステートメントを使用しない場合、SELECT ステートメントはデフォルトでロックされません。また、上記のシナリオでは、排他ロックを使用する必要があります。また、上記の 2 つのステートメントはトランザクション内でのみ有効であり、それ以外の場合は有効になりません。 MySQL コマンドラインでトランザクションを使用する方法は次のとおりです。

AUTOCOMMIT=0 を設定します。 
作業を開始します。 
 a = SELECT num FROM table1 WHERE id=2 FOR UPDATE; 
 テーブル1を更新します。SET num = a.num + 1 WHERE id=2; 
仕事をコミットする。

このように、将来データを更新するたびに、このトランザクションを使用して操作を実行します。同時実行の場合は、後で実行されるトランザクションは、現在のトランザクションが完了するまでブロックされます。 (ロックにより並行性が順次実行に変更されます)

楽観的ロックの使用

楽観的ロックは、変更する必要があるすべてのデータが競合しないことを単純に想定したロック実装のメカニズムです。したがって、更新前にデータをロックするのではなく、データ行のバージョン番号のみを照会します (ここでのバージョン番号はカスタム フィールドであり、ビジネス テーブルに基づいて追加フィールドを追加する必要があり、更新されるたびに自動的に増加または更新されます)。

データを更新する場合、更新条件にバージョン番号情報が追加されます。

  • バージョン番号が変更されない場合は、データ行が更新されておらず、更新条件が満たされているため、更新は成功します。
  • バージョン番号が変わると条件が満たされないためデータ行を更新できません。このときSQL操作が必要となります。 (レコードデータ行を再クエリし、新しいバージョン番号でデータを再度更新します)

練習する

学生テーブルに1回更新ロックをかける練習をする。学生テーブルには1つのデータがある。

2つのクライアントを開く

最初のオープントランザクションの後に実行される

更新のために、ID = 1 の学生から名前を選択します。 

2 番目のトランザクションが開かれた後、同じステートメントが実行され、データが最初のトランザクションによってブロックされていることがわかります。

この時点で、最初のトランザクションが変更を実行してコミットします。

2番目のトランザクションの選択実行が4秒以上ブロックされていることが判明しました

まとめ

一般に、どちらの方法でもデータベースでの同時更新操作をサポートできます。ただし、どちらを使用するかは実際のアプリケーション シナリオによって異なり、アプリケーション シナリオでどちらがより適切にサポートされ、パフォーマンスへの影響が最も少ないかによって異なります。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • 重複したMySQLレコードを現場でチェックし、処理する実践的な記録
  • MySQL の重複データの処理方法 (防止と削除)
  • 重複データの処理に関するMySQL学習ノート
  • MySQLの実行原理、論理階層化、データベース処理エンジンの変更について詳しく説明します
  • MySQLが大量のデータを処理する際にクエリ速度を最適化するいくつかの方法
  • MySQLデータ処理のソートと追加、削除、変更の操作の説明

<<:  MongoDB データベースの状態を監視する Zabbix3.4 メソッド

>>:  Ant Design Blazor コンポーネントライブラリのルーティング再利用マルチタブ機能

推薦する

MySQL Workbenchのダウンロードと使用方法のチュートリアルの詳細な説明

1. MySQL WorkbenchをダウンロードするWorkbench は、MySQL のグラフィ...

CSS でショートカット プロパティを記述する際は、トラブルの順序に注意してください (落とし穴を避けるため)

ショートハンドプロパティは、複数のプロパティに同時に値を割り当てるために使用されます。たとえば、fo...

Navicat for MySql ビジュアルインポート CSV ファイル

この記事では、参考までに、Navicat for MySql の CSV ファイルのビジュアルインポ...

MySql 8.0 と対応するドライバー パッケージの一致に関する注意事項

MySql 8.0 対応ドライバパッケージのマッチングMySql データベースをバージョン 8.0 ...

Javascript イベントキャプチャとバブリングメソッドの詳細な説明

目次1. イベント処理モデル1. イベントバブリング(1)3つのdiv要素にイベントをバインドする(...

モバイルデバイスでインラインスクロールを実装するための4つのソリューションの詳細な説明

ニーズの発見領域の一部のみスクロールでき、残りの部分は移動できない場合、どのような方法を使用しますか...

MySQL シリーズ 6 のユーザーと認証

目次チュートリアルシリーズ1. ユーザー管理1. ユーザーアカウント2. アカウントの追加と削除3....

vue-element-admin プロジェクトのインポートとエクスポートの実装

vue-element-admin インポートコンポーネントのカプセル化テンプレートとスタイルまず、...

JavaScript ES6 分割演算子の理解と応用

目次序文脱構築記号の役割使い方分割割り当ての適用アプリケーションの簡単な紹介JSONデータを抽出する...

Mysql テーブル、列、データベースの追加、削除、変更、クエリの問題の概要

以下は私がまとめた基本的なSQL知識です。主に参考資料として、また将来の他の初心者の助けとして、私自...

CSSの一般的なプロパティ

CSS の背景: background:#00ffee; //背景色を設定するbackground-...

docker+jenkins+node.js の自動デプロイメント環境をゼロから構築する方法

このケースはCentOS 7システムに基づいていますDockerの使用経験がある人に適していますLi...

MySQL ストアド プロシージャで if ステートメントを使用する詳細な例

この記事では、例を使用して、MySQL ストアド プロシージャでの if ステートメントの使用方法を...

GitHub のサードパーティ認証方式を Vue で実装する例

目次OAuth アプリの作成コードを取得するaccess_tokenを取得するユーザー情報を取得する...

HTMLハイパーリンクタグAのTARGET属性の詳細な説明

ハイパーリンク <a> タグはリンク ポイントを表します。これは英語の単語「anchor...