2016-05-07 2 views
0

MySQLの二重支出の問題を処理するための推奨される方法は何ですか?MySQLのトランザクションと二重支出

  1. スタート
  2. 保証さがAbalance >= $x
  3. $xバランスのB
  4. を追加しているアカウントの取引:言う、例えば、私はそうのようBに口座Aから$xを転送するアプリケーションを持っていますDeduct $xAの残高
  5. コミット(またはクエリが失敗した場合はロールバック)

$xAからBに転送するために、2つの同一のトランザクションが同時に実行されるシナリオを検討しています。 Aの残高が少なくとも$xである限り、いずれの取引もまだ残高を更新していないため、ステップ#2のチェックは各取引に合格します。これにより、攻撃者はAの残高全体に対して2つの取引を発行し、両方を実行させることができるため、口座の残高を2倍にすることができます。

これに対抗するための推奨方法は何ですか?これを防ぐには、MySQLの隔離レベルをREPEATABLE_READに設定すれば十分でしょうか?あるいは、Aの残高から差し引くクエリにWHERE balance > $x句が含まれていることを確認し、影響を受ける行がない場合はトランザクションをロールバックすることができます。しかし、私は理想的には、これをDBMSレイヤーで処理したいと思っています。

ありがとうございます!

+1

[mySQLトランザクション対ロックテーブル](http://stackoverflow.com/questions/4226766/mysql-transactions-vs-locking-tables)の可能な複製 –

+0

リンクされた質問のすべての回答を確認してください。 –

+0

手順3と4を逆に開始します。 –

答えて

0

更新時に残高が<のときにエラーをスローするトリガーを作成する可能性があります。

してからちょうど句とそれがゼロより小さい

に更新されてからバランスを妨げるが、常に最初に別に入れる前に口座からお金を取るしようとするところがないとクエリで-xバランスをとるためにバランスを更新アカウント。それはあなたが何かを移転したり購入したりする前に銀行からお金を取る必要があるように論理的にも理にかなっています。なぜあなたは今逆の順序でそれを持っているのかわかりません。