ネットで記事を見ました: プロジェクトで作業する際のビジネス ロジックの必要性により、データ テーブルの 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を追加するだけで、問題は解決できます
|