私は金融システムに取り組んでおり、MySQLのトランザクションに問題があります。MySQLトランザクションはロールバックなしでロールバックできますか?
システムはシンプルな証券取引所で、ユーザーは仮想株式を購入して売ることができます。売買プロセスの完全性を維持するために、私はトランザクションを使用します。 問題は、トランザクションの一部がロールバックされている(またはコミットされていない)が、次のクエリが処理されることがあります。
プロセスは以下の通りです:
- ユーザーのための4つの申し出があるオーダー・ブックでは1000年USD
- のための株式を購入したい250 USDすべてのプランについては
START TRANSACTION
:
- スクリプトUPDATEクエリを実行します(1人のユーザーから別のユーザーにUSDを移動し、反対の方法で共有する)。その後、スクリプトはエントリを履歴テーブルにINSERTします。
- ユーザーは有料です(UPDATE残高)。
- 次のオファーには5と6を繰り返します。 今
COMMIT
重要な部分 - いくつかのケースでポイント5からの変更は保存されませんが、6から、彼らは(私は料金が支払われたことがわかりますが、歴史の中でトランザクションがない)です。 私はこの取引中にROLLBACK
を使用していません。このスクリプトは壊れていません(この場合は手数料が支払われないためです)。
クエリがROLLBACK
クエリなしでロールバックされる可能性はありますか?あるいは、MySQLではCOMMITではなく、最新のクエリをほとんどコミットできませんか?
ご回答ありがとうございます。
いいえ、トランザクションは常にアトミックでなければなりません。それはすべてか何もしません。 – Barmar
システム内の最初の穴は、トランザクションの前に注文帳(唯一)をチェックしているため、変更されている可能性があります。例えばオーダー1が使用されていて、3つの公開オファーが残っている可能性があります。実際のコードに応じて、ステップ5は何もしないかもしれませんが、ステップ6は依然として料金を請求する場合があります。しかしそれは唯一の問題であり、あなたのコンセプトの中にのみあります。あなたが間違って行うことができる他の多くのことがあります(たとえば、myisamの使用、間違ったトランザクションレベルの使用、選択のロックなど...)、他の問題がある可能性があります。また、実際のマネー/バリューを使って取引する場合は、コンサルタントがコードを確認する必要があります。 – Solarflare
最初の投稿(申し訳ありません)では書きませんでしたが、処理を開始する前に 'SELECT FOR UPDATE'を使って行をロックしています。 私はシングルクーポンを処理していますが、クーポンがまだ存在する場合、ユーザーは有効な残高などを持っています。 現在はデモシステムです。 – Zachmian