mysql行ロックの別の解決策

WBOY
WBOYオリジナル
2016-07-25 09:08:471191ブラウズ

ネットで記事を見ました:
原文は以下の通りです:
********************************** ** *********************************************** *** *

プロジェクトで作業する際のビジネス ロジックの必要性により、データ テーブルの 1 つ以上の行に行ロックを追加する必要があります。最も単純な例は書籍の貸し出しシステムです。 id=1のこの本の在庫が1であるが、同時にこの本を借りに来る人が2いると仮定すると、ここでのロジックは

です ID =1の本からrestnumを選択します; --restnum が 0 より大きい場合、更新を実行します ID=1 のブックセットrestnum=restnum-1を更新します

問題が発生します。2人が同時に借りに来た場合、最初の人がselectステートメントを実行するときに、最初の人が時間がかかる前に2番目の人が介入する可能性があります。 bookテーブルを更新すると、2人目の人がデータを見つけましたが、これは実際にはダーティデータでした。最初の人はrestnumの値を1ずつ減らすため、2人目は本を持っているはずですid=1であることが判明したため、updateは実行されませんが、書籍id=1が在庫切れであることが通知されます。これを理解していません。データベースは 1 つの SQL ステートメントを実行するだけであり、その間に他の sql ステートメントが挿入されるかどうかは関係ありません。 sqlステートメントが実行された後、別のセッションが実行されます。したがって、同時実行が発生すると、restnumの最終結果は-1となり、これは明らかに不合理であるため、Mysqlエンジンを使用することができます。 インデックスを通じてデータ行をロックします 。本を借りるための上記の文は次のようになります: 始めます ID =1 のブックからrestnumを選択更新します ;

-- id=1 の行に排他ロックを追加し、その ID にはインデックスが付いています

ID=1 のブックセットrestnum=restnum-1を更新します コミットする このように、2番目の人がselectステートメントを実行すると、最初の人がcommitを実行するまで待機状態になります。これにより、最初のユーザーがデータを変更する前に、2 番目のユーザーがデータを読み取ることがなくなります。 ************************************************ ************************************************* * **

この記事の目的は、行レベルのロックの適用について説明することですが、上記の例のシナリオ (実際、フラッシュ セール システムなど、このシナリオは今でも頻繁に発生します) については、 SQL ステートメントを簡単に変更できます。

update book setrestnum=restnum-1 where id=1 andrestnum>0; 元の update ステートメントの後にrestnum>0を追加するだけで、問題は解決できます
開始;

更新のためにブックセットrestnum=restnum-1を更新 ブックセットrestnum=restnum-1を更新します; 1 とrestnum>0;

コードをコピー



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。