我正在研究金融系统,我遇到了MySQL事务的问题。
该系统是一个简单的股票交易所,用户可以买卖虚拟股票。为了保持买卖过程的完整性,我使用交易。 问题是在某些情况下(我不知道它依赖于什么)一些事务被回滚(或没有提交),但下一个查询被处理。
过程如下:
START TRANSACTION
COMMIT
现在关键部分 - 在某些情况下,从第5点开始的更改不会保存,但是从6开始就是保存(我看到费用已经支付,但历史记录中没有交易)。
我在这次交易中没有使用ROLLBACK
并且脚本没有中断(因为在这种情况下不会支付费用)。
是否有可能在没有ROLLBACK
查询的情况下回滚事务?或者MySQL只能提交几个最新的查询而不是全部查询?
答案 0 :(得分:1)
是否交易,您的客户端代码有责任验证所有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,除非您终止具有挂起更改的会话。
答案 1 :(得分:0)
问这个问题已经很长时间了,但是实际上问题是我没有为每个查询检查SQL错误。
实际上,在某些时候,当我应该回滚事务时,我没有这样做。
如果您正在寻找答案-请再次检查是否在事务中测试了所有查询以成功执行,并且不相信所使用的框架会自动为您执行操作(只需再次检查)。