MySQL 事务
总结:在本教程中,您将了解 **MySQL 事务 **以及如何使用 COMMIT and ROLLBACK 语句来管理 MySQL 中的事务。
MySQL 事务介绍
要了解 MySQL 中的事务是什么,让我们看一个在示例数据库中添加新销售订单的实例。添加销售订单的步骤如下:
- 首先, 从表中查询最新的销售订单号,
orders并使用下一个销售订单号作为新的销售订单号。 - 接下来,在表中插入一个新的销售订单
orders。 - 然后,获取新插入的销售订单号
- 之后,将新的销售订单项目插入
orderdetails带有销售订单编号的 表格中 - 最后,从两者
orders和orderdetails表中选择数据 以确认更改
现在,想象一下如果由于某些原因(例如表锁定)导致上述一个或多个步骤失败,那么销售订单数据会发生什么情况?例如,如果将订单的项目添加到 orderdetails 表中的步骤失败,您将有一个空的销售订单。
这就是为什么事务处理会派上用场。MySQL 事务允许您执行一组 MySQL 操作,以确保数据库永远不会包含部分操作的结果。在一组操作中,如果其中一个操作失败,则会发生回滚以将数据库恢复到其原始状态。如果没有发生错误,则将整个语句集提交到数据库。
MySQL 事务语句
MySQL 为我们提供了以下重要的语句来控制事务:
- 要开始事务,请使用该
START TRANSACTION语句。该BEGIN或BEGIN WORK有的别名START TRANSACTION。 - 要提交当前事务并使其更改永久化,请使用该
COMMIT语句。 - 要回滚当前事务并取消其更改,请使用该
ROLLBACK语句。 - 要为当前事务禁用或启用自动提交模式,请使用该
SET autocommit语句。
默认情况下,MySQL 会自动将更改永久提交到数据库。要强制 MySQL 不自动提交更改,请使用以下语句:
SET autocommit = 0;
或者
SET autocommit = OFF
您可以使用以下语句显式启用自动提交模式:
SET autocommit = 1;
或者
SET autocommit = ON;
MySQL 事务实例
我们将使用示例数据库中的 orders 和 orderDetails 表进行演示。

提交实例
为了使用事务,您首先必须将 SQL 语句分解为逻辑部分,并确定何时提交或回滚数据。
以下说明了创建新销售订单的步骤:
- 首先,使用
START TRANSACTION语句启动事务 。 - 接下来,从
orders表中选择最新的销售订单编号, 并使用下一个销售订单编号作为新的销售订单编号。 - 然后,在
orders表中插入一个新的销售订单 。 - 之后,将销售订单项目插入
orderdetails表中。 - 最后,使用
COMMIT语句提交事务 。
或者,您可以从 orders 和 orderdetails 表中选择数据 来检查新的销售订单。
以下是执行上述步骤的脚本:
-- 1\. start a new transaction
START TRANSACTION;
-- 2\. Get the latest order number
SELECT
@orderNumber:=MAX(orderNUmber)+1
FROM
orders;
-- 3\. insert a new order for customer 145
INSERT INTO orders(orderNumber,
orderDate,
requiredDate,
shippedDate,
status,
customerNumber)
VALUES(@orderNumber,
'2005-05-31',
'2005-06-10',
'2005-06-11',
'In Process',
145);
-- 4\. Insert order line items
INSERT INTO orderdetails(orderNumber,
productCode,
quantityOrdered,
priceEach,
orderLineNumber)
VALUES(@orderNumber,'S18_1749', 30, '136', 1),
(@orderNumber,'S18_2248', 50, '55.09', 2);
-- 5\. commit changes
COMMIT;

要获取新创建的销售订单,请使用以下查询:
SELECT
a.orderNumber,
orderDate,
requiredDate,
shippedDate,
status,
comments,
customerNumber,
orderLineNumber,
productCode,
quantityOrdered,
priceEach
FROM
orders a
INNER JOIN
orderdetails b USING (orderNumber)
WHERE
a.ordernumber = 10426;
这是输出:

回滚实例
首先登录MySQL数据库服务器,删除orders表中的数据:
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> DELETE FROM orders;
Query OK, 327 rows affected (0.03 sec)
从输出中可以看出,MySQL 确认 orders 表中的所有行都已删除。
其次,在单独的会话中登录MySQL数据库服务器,从orders表中查询数据:
mysql> SELECT COUNT(*) FROM orders;
+----------+
| COUNT(*) |
+----------+
| 327 |
+----------+
1 row in set (0.00 sec)
在这第二个会话中,我们仍然可以看到 orders 表中的数据。
我们在第一次会议中进行了更改。然而,这些变化不是永久性的。在第一个会话中,我们可以提交或回滚更改。
出于演示目的,我们将回滚第一个会话中的更改。
mysql> ROLLBACK;
Query OK, 0 rows affected (0.04 sec)
在第一个会话中,我们还将验证 orders 表的内容:
mysql> SELECT COUNT(*) FROM orders;
+----------+
| COUNT(*) |
+----------+
| 327 |
+----------+
1 row in set (0.00 sec)
从输出中可以清楚地看到,更改已回滚。
在本教程中,您学习了如何使用包含 START TRANSACTION COMMI, 和 ROLLBACK 管理事务的 MySQL 事务语句 。