#### 15.7.2.2 自动提交、提交和回滚

[](<>)[](<>)

在`InnoDB`，所有用户活动都发生在事务中。如果[`自动提交`](server-system-variables.html#sysvar_autocommit)启用模式后，每条 SQL 语句自行形成一个事务。默认情况下，MySQL 为每个新连接启动会话[`自动提交`](server-system-variables.html#sysvar_autocommit)启用，因此如果该语句没有返回错误，MySQL 会在每个 SQL 语句之后执行提交。如果语句返回错误，则提交或回滚行为取决于错误。看[第 15.21.5 节，“InnoDB 错误处理”](innodb-error-handling.html).

一个会话有[`自动提交`](server-system-variables.html#sysvar_autocommit)enabled 可以通过显式启动它来执行多语句事务[`开始交易`](commit.html)要么[`开始`](commit.html)声明并以[`犯罪`](commit.html)要么[`回滚`](commit.html)陈述。看[第 13.3.1 节，“START TRANSACTION、COMMIT 和 ROLLBACK 语句”](commit.html).

如果[`自动提交`](server-system-variables.html#sysvar_autocommit)模式在会话中被禁用`设置自动提交 = 0`，会话总是有一个事务打开。一种[`犯罪`](commit.html)要么[`回滚`](commit.html)语句结束当前事务并开始新的事务。

如果会话具有[`自动提交`](server-system-variables.html#sysvar_autocommit)disabled 结束而不显式提交最终事务，MySQL 回滚该事务。

一些语句隐含地结束一个事务，就好像你做了一个[`犯罪`](commit.html)在执行语句之前。有关详细信息，请参阅[第 13.3.3 节，“导致隐式提交的语句”](implicit-commit.html).

一种[`犯罪`](commit.html)意味着在当前事务中所做的更改是永久的，并且对其他会话可见。一种[`回滚`](commit.html)另一方面，语句取消当前事务所做的所有修改。两个都[`犯罪`](commit.html)和[`回滚`](commit.html)全部释放`InnoDB`在当前事务期间设置的锁。

##### 将 DML 操作与事务分组

[](<>)

默认情况下，与 MySQL 服务器的连接以[自动提交](glossary.html#glos_autocommit)启用模式，它会在您执行时自动提交每个 SQL 语句。如果您有使用其他数据库系统的经验，这种操作模式可能会不熟悉，在这些系统中，标准做法是发出一系列[DML](glossary.html#glos_dml)声明并提交它们或将它们一起回滚。

使用多语句[交易](glossary.html#glos_transaction), 使用 SQL 语句关闭自动提交`设置自动提交 = 0`并以[`犯罪`](commit.html)要么[`回滚`](commit.html)作为适当的。要启用自动提交，请使用以下命令开始每个事务[`开始交易`](commit.html)并以[`犯罪`](commit.html)要么[`回滚`](commit.html).以下示例显示了两个事务。第一个是承诺的；第二个是回滚。

```
$> mysql test
```

```
mysql> CREATE TABLE customer (a INT, b CHAR (20), INDEX (a));
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do a transaction with autocommit turned on.
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do another transaction with autocommit turned off.
mysql> SET autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO customer VALUES (20, 'Paul');
Query OK, 1 row affected (0.00 sec)
mysql> DELETE FROM customer WHERE b = 'Heikki';
Query OK, 1 row affected (0.00 sec)
mysql> -- Now we undo those last 2 inserts and the delete.
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM customer;
+------+--------+
| a    | b      |
+------+--------+
|   10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
mysql>
```

###### 客户端语言的交易

在 PHP、Perl DBI、JDBC、ODBC 等 API 或 MySQL 的标准 C 调用接口中，可以发送事务控制语句如[`犯罪`](commit.html)像任何其他 SQL 语句一样以字符串形式发送到 MySQL 服务器，例如[`选择`](select.html)要么[`插入`](insert.html).一些 API 还提供单独的特殊事务提交和回滚函数或方法。
