2017-02-13 19 views
0

私は金融システムに取り組んでおり、MySQLのトランザクションに問題があります。MySQLトランザクションはロールバックなしでロールバックできますか?

システムはシンプルな証券取引所で、ユーザーは仮想株式を購入して売ることができます。売買プロセスの完全性を維持するために、私はトランザクションを使用します。 問題は、トランザクションの一部がロールバックされている(またはコミットされていない)が、次のクエリが処理されることがあります。

プロセスは以下の通りです:

  1. ユーザーのための4つの申し出があるオーダー・ブックでは1000年USD
  2. のための株式を購入したい250 USDすべてのプランについては
  3. START TRANSACTION
  4. スクリプトUPDATEクエリを実行します(1人のユーザーから別のユーザーにUSDを移動し、反対の方法で共有する)。その後、スクリプトはエントリを履歴テーブルにINSERTします。
  5. ユーザーは有料です(UPDATE残高)。
  6. 次のオファーには5と6を繰り返します。
  7. COMMIT

重要な部分 - いくつかのケースでポイント5からの変更は保存されませんが、6から、彼らは(私は料金が支払われたことがわかりますが、歴史の中でトランザクションがない)です。 私はこの取引中にROLLBACKを使用していません。このスクリプトは壊れていません(この場合は手数料が支払われないためです)。

クエリがROLLBACKクエリなしでロールバックされる可能性はありますか?あるいは、MySQLではCOMMITではなく、最新のクエリをほとんどコミットできませんか?

ご回答ありがとうございます。

+1

いいえ、トランザクションは常にアトミックでなければなりません。それはすべてか何もしません。 – Barmar

+0

システム内の最初の穴は、トランザクションの前に注文帳(唯一)をチェックしているため、変更されている可能性があります。例えばオーダー1が使用されていて、3つの公開オファーが残っている可能性があります。実際のコードに応じて、ステップ5は何もしないかもしれませんが、ステップ6は依然として料金を請求する場合があります。しかしそれは唯一の問題であり、あなたのコンセプトの中にのみあります。あなたが間違って行うことができる他の多くのことがあります(たとえば、myisamの使用、間違ったトランザクションレベルの使用、選択のロックなど...)、他の問題がある可能性があります。また、実際のマネー/バリューを使って取引する場合は、コンサルタントがコードを確認する必要があります。 – Solarflare

+0

最初の投稿(申し訳ありません)では書きませんでしたが、処理を開始する前に 'SELECT FOR UPDATE'を使って行をロックしています。 私はシングルクーポンを処理していますが、クーポンがまだ存在する場合、ユーザーは有効な残高などを持っています。 現在はデモシステムです。 – Zachmian

答えて

0

トランザクションは、すべてのINSERTまたはUPDATEクエリが正常に完了したことを検証し、明示的なROLLBACKを発行するか、COMMITで接続を閉じて暗黙的なROLLBACKを発行することをクライアントコードの責任で行います。いずれかに失敗してもコードが実行された場合、それらのクエリは有効になりません(失敗したため)。残りは実行されます。

ここでは簡単な例です:

mysql> create table test (
    ->  id int(10) unsigned not null, 
    ->  primary key (id) 
    ->); 
Query OK, 0 rows affected (0.02 sec) 

mysql> insert into test(id) values (1); 
Query OK, 1 row affected (0.00 sec) 

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> insert into test(id) values (2); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into test(id) values (-3); 
ERROR 1264 (22003): Out of range value for column 'id' at row 1 

我々はロールバックして、ここで中止され、私たちはしなかったはずです。予想

mysql> insert into test(id) values (4); 
Query OK, 1 row affected (0.00 sec) 

mysql> commit; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from test; 
+----+ 
| id | 
+----+ 
| 1 | 
| 2 | 
| 4 | 
+----+ 
3 rows in set (0.00 sec) 

4行が、それ以外は3

を持って、あなたはCOMMIT不要なものの、不要なROLLBACKを得ることができ、多くの状況がそこにいることは、私はあなたがない限り起こることができるか分からないものです保留中の変更を含むセッションを終了します。

関連する問題