MySQLの高いソリューション
Webプログラムはローカルでデバッグするときはすべて正常で、オンラインに置くのも基本的に正常ですが、たまにデータエラーが発生する場合があります.この場合、受注システムでは特によく見られます.ほとんどの受注ステータスの更新は2つのパス(ブラウザのジャンプと支払いサーバの非同期プッシュメッセージ)があるので、もちろん、最終データは非同期の結果に準拠しますが、問題は、ブラウザのジャンプも受注ステータスを更新する必要があります.この2つの方法が短時間でデータベースに同時に到着した場合(一般的には1秒以内)、データベースにロックがかかっていない場合、この受注は2回処理されます.
データテーブルを作成する場合、支払いに関連する場合は、行ロック、トランザクション、外部キーをサポートするInnoDBエンジンを使用します.
文章の最初の解決策はInnoDBを用いて操作するデータ行をロックすることである.
データテーブル構造
オーダーID(プライマリ・キー)
オーダー金額
オーダーステータス
ここでは簡単にするためにいくつかのコアフィールドしか設定されていません.次に、注文を2つの側面で更新します.ブラウザのジャンプ BEGIN;
SELECT * FROM `orders` WHERE `order_id`=100 FOR UPDATE;
//業務ロジックCOMMIT;
コア文は3つ、1つで説明します
1.BEGIN手動でトランザクションをオープンします(ロー・ロックはトランザクションをオープンするクエリーにのみ機能します)
2.FOR UPDATE排他的書き込み(ロックが正常に取得された後、現在のプロセスのみがそのレコードを更新することができ、他のプロセスがそのレコードを更新する必要がある場合、「ロック待ち」を行う必要がある)
3.COMMIT提出処理
2. 支払サーバ非同期プッシュ
処理方法はブラウザと同じで、行ロックをかければ問題ありません.
これでどんなに大きくても同時に来るので、ロックがあるので問題はありません.
データテーブルを作成する場合、支払いに関連する場合は、行ロック、トランザクション、外部キーをサポートするInnoDBエンジンを使用します.
文章の最初の解決策はInnoDBを用いて操作するデータ行をロックすることである.
データテーブル構造
オーダーID(プライマリ・キー)
オーダー金額
オーダーステータス
ここでは簡単にするためにいくつかのコアフィールドしか設定されていません.次に、注文を2つの側面で更新します.
SELECT * FROM `orders` WHERE `order_id`=100 FOR UPDATE;
//業務ロジックCOMMIT;
コア文は3つ、1つで説明します
1.BEGIN手動でトランザクションをオープンします(ロー・ロックはトランザクションをオープンするクエリーにのみ機能します)
2.FOR UPDATE排他的書き込み(ロックが正常に取得された後、現在のプロセスのみがそのレコードを更新することができ、他のプロセスがそのレコードを更新する必要がある場合、「ロック待ち」を行う必要がある)
3.COMMIT提出処理
2. 支払サーバ非同期プッシュ
処理方法はブラウザと同じで、行ロックをかければ問題ありません.
これでどんなに大きくても同時に来るので、ロックがあるので問題はありません.