この記事では、例を使用して MySQL の悲観的ロックと楽観的ロックについて説明します。ご参考までに、詳細は以下の通りです。 悲観的ロックと楽観的ロックは、人間が定義した概念です。並行リソースを処理するための一般的な手段である一種の考え方として理解できます。 これらを、MySQL で提供されているロック メカニズム (テーブル ロック、行ロック、排他ロック、共有ロック) と混同しないでください。 1. 悲観的ロック 名前が示すように、データ処理に対して悲観的であり、同時実行の競合が発生することを常に信じ、データを取得および変更するときに他の人がデータを変更することを意味します。したがって、データ処理プロセス全体を通じてデータをロックする必要があります。 悲観的ロックの実装は通常、MySQL の排他ロック、select .... for update などのデータベースが提供するロック メカニズムに依存して悲観的ロックを実装します。 例: フラッシュセール中は、過剰販売を避けるために在庫数量が削減されます。 テーブル `tb_goods_stock` を作成します ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID', `nums` int(11) unsigned DEFAULT '0' COMMENT '製品在庫数', `create_time` datetime DEFAULT NULL COMMENT '作成時刻', `modify_time` datetime DEFAULT NULL COMMENT '更新時間', 主キー (`id`)、 ユニークキー `goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='製品在庫テーブル'; データベース レベルで負の数が発生しないように、製品在庫数量の数値フィールド タイプを unsigned に設定します。 悲観的ロックを使用するには、MySQL の自動コミット機能をオフにして、autocommit = 0 を設定する必要があることに注意してください。 MySQL の行レベルのロックはインデックスに基づいていることに注意してください。SQL がインデックスを使用しない場合、テーブル全体のロックにはテーブルレベルのロックが使用されます。 1. トランザクションを開始し、販売する製品を照会し、レコードをロックします。 始める; 更新のために、goods_id = {$goods_id} である tb_goods_stock から数値を選択します。 2. 商品の数量が購入数量より多いかどうかを判断します。満足できない場合は、トランザクションをロールバックします。 3. 条件が満たされた場合は、在庫を減らしてトランザクションをコミットします。 tb_goods_stock を更新し、nums = nums - {$num} を設定します。 ここで、goods_id = {$goods_id} かつ nums >= {$num} です。 専念; トランザクション中に保持されたロックは、トランザクションがコミットされると解除されます。 悲観的ロックは、最初にロックしてから同時実行制御でデータを処理するという保守的な戦略を採用しています。データ処理のセキュリティは確保されますが、効率も低下します。 2. 楽観的ロック 名前が示すように、これはデータ処理に対して楽観的な姿勢を取り、データが一般的に競合しないという楽観的な考えを持つことを意味します。データの更新を送信するときにのみ、データの競合が検出されます。 競合が見つかった場合は、エラー メッセージがユーザーに返され、ユーザーは続行方法を決定できます。 楽観的ロックの実装は、データベースが提供するロック メカニズムに依存せず、自分で実装する必要があります。実装方法は一般的にデータ バージョンを記録するもので、1 つはバージョン番号によるもので、もう 1 つはタイムスタンプによるものです。 テーブルにバージョン番号またはタイムスタンプフィールドを追加します。データを読み取るときは、バージョン番号も一緒に読み取ります。データが更新されると、バージョン番号が 1 増加します。 データの更新を送信するときに、現在のバージョン番号が最初に読み取られたバージョン番号と等しいかどうかを判断します。等しい場合は更新されます。等しくない場合は、データは期限切れとみなされ、更新は拒否され、ユーザーは再度操作する必要があります。 テーブル `tb_goods_stock` を作成します ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID', `nums` int(11) unsigned DEFAULT '0' COMMENT '製品在庫数', `create_time` datetime DEFAULT NULL COMMENT '作成時刻', `modify_time` datetime DEFAULT NULL COMMENT '更新時間', `version` bigint(20) unsigned DEFAULT '0' COMMENT 'バージョン番号', 主キー (`id`)、 ユニークキー `goods_id` (`goods_id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='製品在庫テーブル'; 1. 販売する製品を照会し、バージョン番号を取得します。 始める; tb_goods_stock から、goods_id = {$goods_id} である nums、version を選択します。 2. 商品の数量が購入数量より多いかどうかを判断します。満足できない場合は、トランザクションをロールバックします。 3. 条件が満たされた場合は、在庫を削減します。 (アップデートの際は、現在のバージョンが手順1で取得したバージョンと同じかどうかを確認してください) tb_goods_stock を更新し、nums = nums - {$num}、version = version + 1 に設定します。 ここで、goods_id = {$goods_id} version = {$version} かつ nums >= {$num}; 4. 更新操作が正常に実行されたかどうかを判断します。成功した場合はコミットし、そうでない場合はロールバックします。 楽観的ロックはプログラムに基づいて実装されるため、デッドロックが発生せず、読み取りが多いアプリケーションのシナリオに適しています。競合が頻繁に発生すると、上位アプリケーションがユーザーに再操作を要求し続けることになり、パフォーマンスが低下します。この場合は、悲観的ロックがより適しています。 MySQL 関連のコンテンツにさらに興味がある読者は、次のトピックを確認してください: 「MySQL データベース ロック関連スキルの概要」、「MySQL ストアド プロシージャ スキルの概要」、「MySQL 共通関数の概要」、「MySQL ログ操作スキルの概要」、および「MySQL トランザクション操作スキルの概要」。 この記事が皆様のMySQLデータベース設計に役立つことを願っています。 以下もご興味があるかもしれません:
|
<<: iptables の再起動後に Docker の iptables ルールの完全なプロセスが失われる
>>: Vueを使用して天気コンポーネントをロードする方法の詳細な説明
間違いNavicat Premium を使用して MySQL に接続すると、次のエラーが発生します。...
目次ルーティングプラグインをモジュール方式で使用するルートの使用宣言型ナビゲーションプログラムによる...
1. MySQL ユーザー管理[例1.1] ローカルMySQLサーバーのテストデータベースにroot...
この記事では、CSSの透明な境界線の背景クリップの素晴らしい使い方を主に紹介し、みんなと共有し、自分...
CSS3 の角丸や影の効果を使ったページを作りたいのですが、IE ブラウザでは対応していません。こ...
この記事では、Vueの具体的なコード例を参考までに紹介します。具体的な内容は以下のとおりです。必要:...
この記事では、例を使用して、MySQL データベースのデータ テーブルの最適化、外部キーの使用、およ...
目次JavaScript プロトタイプチェーンオブジェクトプロトタイプトップレベルのプロトタイプOb...
React Hooks は React 16.8 で導入された新しい機能で、クラスを使用せずに状態や...
この記事では、簡単なドラッグ効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...
序文:インストール プロセスについては詳しく説明しません。問題に直接触れましょう。MySQL のリモ...
Linux のデフォルトの ssh リモート ポートは 22 です。デフォルトのポートは、悪意のある...
MySQL をクリーンアンインストールします。個人的にテストしたところ、今回はようやくうまくいきま...
MySQLはレプリケーションフィルターを動的に変更します今日遭遇した問題についてお話しします。今日は...
絶対、相対、固定位置の位置決めabsolue: 絶対配置。上、下、左、右を使用して、配置先の親要素に...