1

少し前に構築したこのオンライン ショップがあり、製品在庫テーブルで LOCK TABLES を使用して、在庫が 0 を下回ったり、適切に更新されなかったりしないようにしています。

最近、データベースに多くのトラフィックと多くの操作 (他の LOCK TABLES も) があったため、データの一貫性を維持するためのより高速で安全な方法がないか自問自答しています。

トランザクションとその仕組みを理解しようとしていますが、次のロジックがチェックアウト プロセスにうまく適用されるかどうか疑問に思っています。

1) START TRANSACTION (これにより、いずれかのクエリが失敗した場合、または在庫などの他の条件が必要以上に低い場合に、後続のクエリをロールバックできます)

2) 「customers」テーブルに顧客を挿入します

3) 'orders' テーブルに注文情報を挿入する

4) 異なるテーブルへの同様のクエリ

5) カート内の各製品について:

5.1) update products set stock = stock - x where stock - x >= 0 (x は顧客が購入したい単位)

5.2) 影響を受ける行を確認し、影響を受ける行 == 0 の場合は ROLLBACK して終了します (現在の製品の在庫が不足しているため、注文をキャンセルするか、エラーをスローします)。

5.3) その他のクエリ...など

6) コミット

その音は正しいですか?

私が得られない (そして、そもそも心配する必要があるかどうかわからない) のは、同時セッション (別の顧客) が同じものを配置しようとした場合に、「製品」テーブルと在庫数に何が起こるかです。注文または同じ商品の一部を含む注文。

2 番目のトランザクションは最初のトランザクションが終了するのを待ち、2 番目のトランザクションは最新の在庫数を使用しますか、それとも両方が同時に実行され、場合によっては両方が失敗する可能性がありますか?

4

1 に答える 1

2

手順 2 (顧客の詳細を保存する) をトランザクションから外しますが、ワークフローは正しいです。注文できなかったとしても、おそらく顧客を覚えておきたいでしょう。

トランザクション内で行が更新されると、トランザクションが終了するまで、その行 (または場合によってはテーブル全体) が排他モードでロックされます。在庫を更新しようとすると、同じ製品を同時に注文しようとすると保留になる可能性があります。

最初のトランザクションがコミット (またはロールバック) されると、ロックが解放され、同時更新によって新しい値が更新されます。

推奨される読み物:このマニュアルの章の全文、特にこのページ。はい、たくさんあります (ただし、最初にすべてを理解できなくても心配しないでください。うさぎの穴は非常深いものです) 。

于 2013-08-03T00:16:08.053 に答える