在 InnoDB
中,所有用户活动都在事务中进行。如果启用了 autocommit
模式,每个 SQL 语句本身构成一个单独的事务。默认情况下,MySQL 以启用了 autocommit
的方式启动每个新连接的会话,因此,如果语句没有返回错误,MySQL 会在每个 SQL 语句之后执行 commit。如果语句返回错误,commit 或 rollback 行为取决于错误。请参阅 第 17.20.5 节,“InnoDB 错误处理”。
启用了 autocommit
的会话可以通过以显式 START TRANSACTION
或 BEGIN
语句开始,并以 COMMIT
或 ROLLBACK
语句结束,来执行多语句事务。请参阅 第 15.3.1 节,“START TRANSACTION、COMMIT 和 ROLLBACK 语句”。
如果在一个会话中使用 SET autocommit = 0
禁用了 autocommit
模式,该会话始终处于打开事务状态。一个 COMMIT
或 ROLLBACK
语句会结束当前事务,并开始一个新的事务。
如果一个禁用了 autocommit
的会话在没有显式 commit 最后一个事务的情况下结束,MySQL 会回滚该事务。
某些语句会隐式结束事务,就好像您在执行该语句之前执行了 COMMIT
一样。有关详细信息,请参阅 第 15.3.3 节,“导致隐式 commit 的语句”。
一个 COMMIT
表示当前事务中所做的更改已永久保存,并对其他会话可见。另一方面,一个 ROLLBACK
语句会取消当前事务所做的所有修改。 COMMIT
和 ROLLBACK
都会释放当前事务期间设置的所有 InnoDB
锁。
默认情况下,连接到 MySQL 服务器时,会启用 autocommit 模式,它会自动提交您执行的每个 SQL 语句。如果您有使用其他数据库系统的经验,这种操作模式可能不熟悉,因为在其他数据库系统中,通常的做法是发出一系列 DML 语句,然后将它们一起提交或回滚。
要使用多语句事务,请使用SQL语句SET autocommit = 0
关闭自动提交,并在每个事务的末尾使用COMMIT
或ROLLBACK
,具体取决于操作。要保持自动提交,请在每个事务的开头使用START TRANSACTION
,并在其末尾使用COMMIT
或ROLLBACK
。以下示例展示了两个事务,第一个被提交,第二个被回滚。
$> 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或MySQL标准C调用接口等API中,可以像发送其他SQL语句(例如SELECT
或INSERT
)一样,将事务控制语句(如COMMIT
)作为字符串发送到MySQL服务器。一些API还提供单独的特殊事务提交和回滚函数或方法。