0

これが私のセットアップです: 30 分の時間枠 (1 時間と 30 分) を含む MySQL データベースのテーブル 各時間枠で予約可能な部屋数を一定期間表示する Web サイト。最小予約は 1 時間なので、各予約は少なくとも 2 つのスロットを予約し、予約された場合、それらが利用できなくなる前にスロットを予約します (30 分間部屋を予約することはできません)。

私の質問は次のとおりです。php スクリプトで PDO トランザクションを使用して、状態 (列挙型の 2 つの列) を変更することにより、予約用に多数のスロットを予約します。では、2 人以上の顧客が同じ時間帯またはおそらくその前の時間帯に部屋を予約しようとした場合、SELECT FOR UPDATE を使用するとどうなりますか? 最初のものは手順を続行し、他のものは (エラーまたは空のセットによって) 拒否されますか、それとも最初のものが終了した後、他のものは待機し、彼が予約した場合はデータベースの変更をコミットしますか、場合はロールバックしますか?彼は考えを変え、その後、2番目に速い顧客が行を選択して更新しようとするか、最初の顧客のアクションに依存しないか?

基本的に、ある種の再試行システムを実装する必要があるかどうかを知りたいです。

また、一時的なロックが解除されるのはいつなのか気になりました。トランザクションの場合にトランザクションがコミットされた後(mysql、自動コミットオフの両方)、またはselectステートメントの一部/すべての行に影響する次の更新時にのみ?

4

1 に答える 1

-1

基本的に、PDO では、トランザクション (beginTransactionメソッドで開始) は、autocomit を false に設定することで「エミュレート」されます。そのため、select to update との同時アクセスのリスクが小さい場合でも、存在します。

$db->query('START TRANSACTION')その後、SQL ステートメントを使用してトランザクションを開始できます。db->query('COMMIT');もちろん、障害が発生した場合は、db->query('ROLLBACK'); 通常、問題を回避できます。確実にしたい場合は、トランザクション内で使用できます$db->query('LOCK TABLE ...');

Transaction を使用すると、テーブルにゴミが入らないように、すべてが同時に送信されます。すべてのトランザクション (デフォルトでは 1 つのクエリがトランザクション) が次々に実行されるため、理論的には、これにより同時アクセスから保護されます。しかし、問題は SELECT を使用して更新することです。トランザクションがあなたを保護せず、別の良いデータを黙って削除するというエッジケースがあると思います。

エッジケースが許可されていないため、ロックテーブルはそのために役立ちます。問題は、ロックを長時間保持しすぎると、エラーが送信されることです。

于 2012-11-25T09:53:43.380 に答える