INSERT是否自动提交?


13

我们的应用程序向MySQL数据库触发INSERT查询以添加记录。我想知道记录是否自动提交。如果我运行ROLLBACK命令,数据库何时执行回滚?提交后是否可以回滚?


为了澄清起见,由于InnoDB使用COMMIT / ROLLBACK,我在19小时前将其标记为“ innodb”。
RolandoMySQLDBA 2011年

+1可以提醒开发人员和DBA注意事务行为,支持事务的相应应用程序范式及其后果(好坏)。
RolandoMySQLDBA 2011年

我回答了你的问题,并在评论下加了评论。
RolandoMySQLDBA 2011年

Answers:


10

问题的答案取决于您是否在一项涉及多个语句的事务中。(您已使用InnoDB标记了问题,而MyISAM的答案将有所不同。)

从参考手册中:http : //dev.mysql.com/doc/refman/5.1/en/commit.html

默认情况下,MySQL在启用自动提交模式的情况下运行。这意味着,一旦执行更新(修改)表的语句,MySQL就会将更新存储在磁盘上以使其永久化。

因此,是的,默认情况下,如果您仅使用INSERT,则将提交您插入的记录,并且没有必要尝试回滚它们。(这实际上与在BEGIN和之间包装每个语句相同COMMIT。)

但是,如果您要显式处理事务,则必须使用COMMIT来提交存储记录,但也可以使用ROLLBACK

您可以使用START TRANSACTION(或BEGIN)显式启动事务。这与autocommit设置无关(默认情况下处于启用状态):

使用START TRANSACTION,自动提交将保持禁用状态,直到您使用COMMIT或ROLLBACK结束事务。然后,自动提交模式将恢复为之前的状态。

另外,如果autocommit=0我认为在事务的另一端之后有任何语句将启动事务(但是您仍然可以START TRANSACTION显式使用);至少这是我解释的方式:

自动提交模式。如果设置为1,对表的所有更改将立即生效。如果设置为0,则必须使用COMMIT接受事务或使用ROLLBACK取消它。如果autocommit为0,并将其更改为1,则MySQL对所有打开的事务执行自动COMMIT。开始事务的另一种方法是使用START TRANSACTION或BEGIN语句。请参见第12.3.1节“开始事务,提交和回滚语法”。

更具体地说,“另一种开始事务的方式”似乎意味着设置“ autocommit = 0”足以启动事务(至少恰好在开始会话的每个语句之前或在COMMIT/之后ROLLBACK)。我会建议使用BEGINSTART TRANSACTION明确反正就算autocommit=0,因为它可以更清楚地看到在事务开始或结束时。

(如何开始事务可能取决于应用程序使用MySQL的方式。)


1
为完全定义事务协议而值得+1。
RolandoMySQLDBA 2011年

@Bruno,对于MyISAM,其中“ commit”和“ rollback”不起作用,插入是否不会半提交?
Pacerier,2015年

7

默认情况下,InnoDB设置为autocommit = 1或ON一旦提交,便无法回滚

您必须执行以下两项操作之一才能禁用它:

选项1:将其添加到/etc/my.cnf并重新启动mysql

[mysqld]
autocommit=0

选项2:在开始任何有意义的SQL之前,请在开放式数据库连接中执行其中一项操作

SET autocommit = 0;
START TRANSACTION;

在这两个选项下,您将必须执行手动COMMIT或手动ROLLBACK

警告

如果表是MyISAM,则说明更为简单。由于MyISAM存储引擎没有事务,因此执行的所有INSERT,UPDATE和DELETE都是永久的。没有任何回滚。


为了进一步说明,我的回答同时针对InnoDB和MyISAM存储引擎。
RolandoMySQLDBA 2011年

1
万一InnoDB中的“自动提交”处于关闭状态,而我的应用程序正在触发“插入查询”,而我却忘记了执行“提交”,更改丢失多久了?
RPK

如果您的应用程序在每次INSERT之后手动触发COMMIT,它将被写入并且无法删除。如果数据库连接在您提交之前就死了,那么所有更改都将丢失并且会发生回滚。如果执行任何DDL(CREATE TABLE,DROP TABLE,ALTER TABLE等)或手动发出表锁,则将自动提交INSERT。如果使用START TRANSACTION,则会提交所有未提交的更改。
RolandoMySQLDBA 2011年

1
关于“如果您使用START TRANSACTION,则所有未提交的更改都将被提交。” (在DDL的上下文中,否则它将回滚),之前还有一个隐式提交(根据文档,此隐式提交来自5.5.3版)。
布鲁诺

1
“如果使用START TRANSACTION,则所有未提交的更改都将被提交。” -我从MySQL 5.0认证研究指南(ISBN 0-672-32812-7)第418页中得到了这个想法,该页面的名称为START TRANSACTION,SET AUTOCOMMIT = 1,LOCK TABLES,UNLOCK TABLES,TRUNCATE TABLE,RENAME TABLE,DROP INDEX,DROP TABLE ,“ DROP DATABASE”,“ CREATE INDEX”,“ BEGIN”和“ ALTER TABLE”标题下的“在某些情况下,当前事务可能隐式结束:如果发出以下任何语句,则InnoDB隐式提交当前事务的先前未提交的语句并开始执行新交易”。
RolandoMySQLDBA 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.