在MySQL文档中,我得到了以下内容(关于错误代码):
在这个语句中,它明显区别了语句回滚和事务回滚。我的问题是,如何回滚语句,而在其中运行的事务不会回滚?更重要的是,我在事务中获得了这样的锁定超时,并且回滚了整个事务。有人能告诉我这件事吗?
发布于 2016-01-21 15:10:49
与事务类似,语句也是原子的。一旦语句开始执行数据更改,则保存原始状态(实际上记录了更改)。如果语句因任何原因而失败(超时,与刚刚提交的事务冲突),则更改必须恢复到原始状态。语句将报告失败,但事务仍处于打开状态,您可以继续处理事务,就像语句从未执行过一样。
这实际上与savepoint类似--您可以想象,在记录每个语句之前,在语句完成之后,保存点被提交。然而,这对外部事务或保存点没有影响。
发布于 2019-10-30 15:50:48
接受的答案是完全正确和好的,但是我最后在同一个文档页面上做了一个快速的测试设置,而且由于评论太短,如果您愿意自己测试和查看行为,下面是设置:
1)初始化表
CREATE TABLE `x` (
`id` INT(10) UNSIGNED NOT NULL,
`xx` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
INSERT INTO X (id, xx) VALUES (1,NULL),(2,NULL),(3,NULL);2)打开客户端连接,启动事务,启动INSERT以锁定新创建的表中的一行
START TRANSACTION;
INSERT INTO X (id, xx) VALUES (1, 5) ON DUPLICATE KEY UPDATE xx = VALUES(xx);不要提交事务
3)打开第二个客户端连接,启动事务,然后在未锁定的行上触发另一个INSERT
START TRANSACTION;
INSERT INTO X (id, xx) VALUES (2, 7) ON DUPLICATE KEY UPDATE xx = VALUES(xx);再说一次,不要犯。
到目前为止,如果发出一个SELECT * FROM x,那么客户机1将看到"1,5;2,空,3; NULL“,而客户机2将看到"1,NULL;2,7;3,NULL”。
4)在客户端2上触发一个锁定的INSERT,并等待它使用SQL 1025死亡:
INSERT INTO X (id, xx) VALUES (1, 6) ON DUPLICATE KEY UPDATE xx = VALUES(xx);现在,如果在客户机2上发出SELECT * FROM x,我们仍然会看到"1,NULL;2,7;3,NULL“,所以语句被回滚了。如果我们在客户机1上发出它,我们还会看到" 1,5;2,NULL;3,NULL“,因此客户机2事务仍然在运行(假设您的客户机没有被配置为在每个SQL错误上自动回滚)。
5)现在,如果在两个客户机上发出ROLLBACK,表将被“还原”为所有空值。如果您COMMIT它,则得到"1,5;2,7,3,NULL“(在回滚"1,6”时找不到“1,6”,但客户端2事务已被执行)
https://stackoverflow.com/questions/34924495
复制相似问题