1

たとえば、普通預金口座と当座預金口座が 1 つずつあります。私の普通預金口座の残高は 150 ドルです。普通預金口座から当座預金口座に 100 ドルを送金しようとしています。また、普通預金口座から友人の口座に 100 ドルを送金しようとしています。

普通預金口座から当座預金口座に 100 ドルを送金する手順:

1.1。Read(現在の貯蓄残高)

1.2. Saving_balance を 100 減らす

1.3。私のchecking_balanceに100を追加

私の普通預金口座から友人の口座に 100 ドルを送金する手順:

2.1. Read(現在の貯蓄残高)

2.2. Saving_balance を 100 減らす

2.3. 友達のアカウント残高に 100 を追加

これらのトランザクションを同時に実行したい。両方が最初に Saving_balance を読み取った場合、両方とも Saving_balance を 100$ 減らすことができますが、成功できるのはどちらか 1 つだけです。これは銀行システムでどのように処理されますか。

4

3 に答える 3

0

シリアライズ可能な分離レベルは必要ありません (ただし、正確なログイン セマンティクスはデータベース システムごとに大きく異なります)。

  • 最初のステートメントとして select for update を実行してから、残りのトランザクションを実行します。select for update を実行する最初のトランザクションは行をロックし、他のトランザクションは最初のトランザクションがコミットされるまでブロックされます (悲観的ロック)。
  • update ステートメントが実行されたときに、それが読み取られたときと同じ値を保持していることを確認してください。そうでない場合は、再実行してください。

  • データを明示的に読み取る必要はなく、単純な更新ステートメントで十分です (ただし、アカウントに十分な資金があるかどうかをチェックするロジックが必要です。これはトリガーで実現できます)。

于 2013-02-23T04:14:09.700 に答える
0

tSQL でそれを行う方法は次のとおりです。データベースの構文は異なる場合があります。

BEGIN TRAN

UPDATE  accounts
SET balance = balance-100
WHERE   account='1'

UPDATE  accounts
SET balance = balance + 100
WHERE   account='2'

COMMIT TRAN

DB トランザクションをより理解するために、この記事を読むことをお勧めします。

コメントで行われているシリアル化可能な分離の会話全体を無視してください。あなたが説明した問題に実際には対処していません。

于 2013-02-23T04:49:15.867 に答える
0

2 つの実際のトランザクション (1. 100 ドルを当座預金口座に送金する。2. 100 ドルを友人に送金する) があり、試みているのは単一の技術トランザクション (begin;...;commit) でそれを行うことです。これは間違った方法だと思います。コードは実際のトランザクションを反映する必要があります。... 1. 100 ドルを当座預金口座に送金します。;専念; 始める; ... 2. $100 を友達に送金します)。;専念; すべてのトランザクションの前に残高をチェックし、保存するかどうかを決定するデータベース機能を用意してください。

于 2013-02-23T04:31:30.340 に答える