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 表进行演示。

MySQL 交易:订单和订单详情表
MySQL 交易:订单和订单详情表

提交实例

为了使用事务,您首先必须将 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;

MySQL 事务实例
MySQL 事务实例

要获取新创建的销售订单,请使用以下查询:

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 事务实例顺序
MySQL 事务实例顺序

回滚实例

首先登录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 事务语句 。