我正在研究金融系统,我遇到了MySQL事务的问题。
该系统是一个简单的股票交易所,用户可以买卖虚拟股票。为了保持买卖过程的完整性,我使用交易。问题是在某些情况下(我不知道它依赖于什么)一些事务被回滚(或没有提交),但是下一个查询被处理。
该过程如下:
START TRANSACTION
COMMIT
现在关键部分 - 在某些情况下,从第5点开始的更改不会保存,但是从6开始就是保存(我看到费用已经支付,但历史记录中没有交易)。我在这次交易中没有使用ROLLBACK
而且脚本没有破坏(因为在这种情况下不会支付费用)。
如果没有ROLLBACK
查询,交易是否有可能回滚?或者MySQL COMMIT只能提供几个最新的查询而不是全部?
是否交易,您的客户端代码负责验证所有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,除非你终止一个有未决更改的会话。