简体   繁体   English

MySQL 事务可以在没有 ROLLBACK 查询的情况下回滚吗?

[英]Can MySQL transaction rollback without ROLLBACK query?

I'm working on a financial system and I've got a problem with the MySQL transactions.我正在研究一个金融系统,但我遇到了 MySQL 事务的问题。

The system is a simple stock exchange, where users can buy and sell virtual shares.该系统是一个简单的证券交易所,用户可以在其中买卖虚拟股票。 To keep integrity in buy and sell process I use transactions.为了在买卖过程中保持诚信,我使用交易。 The problem is that in some cases (I don't know what it depends on) some of transactions are rolled back (or not commited), but next queries are processed.问题是在某些情况下(我不知道它取决于什么)一些事务会回滚(或未提交),但会处理下一个查询。

The process is following:过程如下:

  1. User wants to buy shares for 1000 USD用户想以 1000 美元购买股票
  2. In orderbook there are 4 offers for 250 USD在订单簿中有 4 个 250 美元的优惠
  3. START TRANSACTION
  4. For every offer:对于每个优惠:
  5. Script does a UPDATE query (moving USD from one user to another and shares in the opposite way).脚本执行 UPDATE 查询(将美元从一个用户移动到另一个用户并以相反的方式共享)。 Then script INSERTs entries to history tables.然后脚本 INSERTs 条目到历史记录表。
  6. Users pay a fee (UPDATE balances).用户支付费用(更新余额)。
  7. Repeat 5 and 6 for the next offer.对下一个报价重复 5 和 6。
  8. COMMIT

Now the key part - in some cases changes from point 5 are not saved, but from the 6 they are (I see that fee was paid, but there is no transaction in the history).现在是关键部分 - 在某些情况下,第 5 点的更改没有保存,而是从第 6 点开始保存(我看到已支付费用,但历史记录中没有交易)。 I'm not using ROLLBACK during this transactions and the script is not breaking (because in this case fee wouldn't be paid).在此交易期间我没有使用ROLLBACK并且脚本没有中断(因为在这种情况下不会支付费用)。

Is there any possibility that transaction is rolling back without ROLLBACK query?事务是否有可能在没有ROLLBACK查询的情况下ROLLBACK Or can MySQL COMMIT only few newest queries instead of all?或者 MySQL 可以只提交几个最新的查询而不是全部?

Transactions or not, it's the responsibility of your client code to verity that all your INSERT or UPDATE queries complete successfully and then either issue a explicit ROLLBACK or close the connection withour COMMIT to issue an implicity ROLLBACK.事务与否,您的客户端代码有责任验证所有 INSERT 或 UPDATE 查询是否成功完成,然后发出显式 ROLLBACK 或关闭与我们的 COMMIT 的连接以发出隐式 ROLLBACK。 If any of them fails but your code goes on, those queries will not take effect (because they failed) but the rest will do.如果其中任何一个失败,但您的代码继续运行,这些查询将不会生效(因为它们失败了),但其余的会生效。

Here's a simplified example:这是一个简化的示例:

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

We should have rollbacked and aborted here, but we didn't.我们应该在这里回滚和中止,但我们没有。

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 rows expected, got 3.预计 4 行,得到 3。

Other than that, there're many circumstances where you can get an unwanted COMMIT but an unwanted ROLLBACK is something I'm not sure that can happen unless you terminate a session with pending changes.除此之外,在很多情况下,您可以获得不需要的 COMMIT 但不需要的 ROLLBACK 是我不确定会发生的事情,除非您终止具有挂起更改的会话。

It's long time since the question was asked, but the problem actually was that I didn't check for the SQL errors for every query.问这个问题已经很长时间了,但问题实际上是我没有检查每个查询的 SQL 错误。

Actually at some points, when I should rollback transaction, I didn't do it.实际上在某些时候,当我应该回滚事务时,我没有这样做。

If your are looking for answer - check again if you testing ALL queries in your transaction for successful execution and don't trust that the framework you are using is doing it for you automatically (just check it again).如果您正在寻找答案 - 再次检查您是否测试了事务中的所有查询以成功执行,并且不要相信您正在使用的框架会自动为您执行(只需再次检查)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM