ロックテーブルは、あなたがロックされてきた行/テーブルに影響を与えることから、他のDBのユーザーを防ぎます。しかし、ロック自体は、あなたのロジックが一貫した状態で出てくることを保証するものではありません。
銀行システムを考えてください。請求書をオンラインで支払うと、取引の影響を受けるアカウントが少なくとも2つあります。そして、お金が転送される受信者のアカウント。また、銀行の口座には、取引に課されたすべてのサービス料を喜んで預ける予定です。 (誰もがこれらの日を知っているとして)与えられた銀行は非常に愚かであることを、のは、彼らのシステムがこのように動作します言わせて:
今
$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;
$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance + $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance
、ロックなしの取引がないと、このシステムは、最大の様々な競合状態に対して脆弱ですこれはあなたの口座で複数の支払いが行われているか、受取人の口座が並行して行われているかを示します。あなたのコードが残高を取得していて、huge_overdraft_fees()とそれ以外のものを実行している間に、他の支払いで同じタイプのコードが並行して実行される可能性があります。彼らはあなたの残高($ 100など)を取得し、トランザクション(あなたが支払っている$ 20を取り除きます、そして彼らはあなたを悩ませています)を行い、両方のコードパスに$ 80と$ 70ドル。最後に終了したものに応じて、$ 50 - $ 100 - $ 20 - $ 30の代わりに、アカウントの2つの残高のいずれかになります。この場合、「あなたの好意での銀行の誤り」。
ここで、ロックを使用するとします。請求書の支払い($ 20)が最初にパイプに当たって、アカウントレコードを獲得してロックします。今、あなたは排他的な使用を持っており、残高から20ドルを差し引いて、新しい残高を平和に書き戻すことができます。あなたのアカウントは、予想通り$ 80で終わります。しかし...うーん...あなたは受信者のアカウントを更新しようとすると、ロックされ、コードよりも長い時間ロックされ、トランザクションがタイムアウトします...私たちは愚かな銀行を扱っているので、コードはちょうどexit()
を引っ張って、あなたの$ 20は電子のパフに消えます。今あなたは20ドル外れですが、あなたはまだ20ドルの手紙を受け取っています。あなたの電話は取り戻されます。
だからトランザクションを入力してください。あなたは取引を開始し、あなたの口座から$ 20を引き落とし、$ 20で信用を得ようとすると、何かが再び爆発する。しかし今度は、exit()
の代わりに、rollback
とコードを実行するだけで、あなたの20ドルはあなたのアカウントに魔法のように追加されます。最後に
、それはこれに沸く:
ロックは、あなたが扱っているすべてのデータベースレコードに干渉から誰を保ちます。トランザクションは、「後の」エラーがあなたが行った「以前の」ことを妨げないようにします。どちらも単独では物事が最終的には正常に機能することを保証することはできません。しかし一緒に、彼らはします。
明日のレッスン:デッドロックの喜び。
私はまだ/まだ混乱しています。受取人の口座に100ドルの口座があり、口座から20ドルの支払いを追加しているとします。私がトランザクションを理解することは、トランザクションを開始するときに、トランザクション内の操作では、トランザクションの開始時の状態でデータベースが認識されるということです。すなわち、私たちがそれを変更するまで、レシーバ口座は$ 100です。それで... 20ドルを追加すると、実際には120ドルの残高が設定されました。しかし、取引中に誰かがレシーバアカウントを$ 0にしてしまったらどうなりますか?これは何とか防止されていますか?彼らは魔法のように$ 120をもう一度手に入れますか?これもロックが必要な理由ですか? – Russ
はい、それがロックが作用する場所です。適切なシステムはレコードの書き込みロックを行い、トランザクションの進行中に誰もレコードを更新できないようにします。編集的システムはレコードに無条件ロックをかけるので、誰も「失効した」残高を読むことはできません。 –
基本的には、トランザクションをコードパス内のセキュリティで保護されたものとして扱います。ロックは、「並列」コードパスを介して物事を安全にします。デッドロックが発生するまで... –