轻松上手,快乐学习!

MySQL 教程

MySQL 首页MySQL 介绍MySQL 安装MySQL 实例库下载MySQL 实例库导入MySQL SELECTMySQL DISTINCTMySQL ORDER BYMySQL WHEREMySQL ANDMySQL ORMySQL INMySQL BETWEENMySQL LIKEMySQL LIMITMySQL IS NULLMySQL 别名MySQL JOINSMySQL INNER JOINMySQL LEFT JOINMySQL RIGHT JOINMySQL CROSS JOINMySQL SELF JOINMySQL GROUP BYMySQL HAVINGMySQL ROLLUPMySQL 子查询MySQL 派生表MySQL EXISTSMySQL CTEMySQL 递归 CTEMySQL UNIONMySQL INTERSECTMySQL MINUSMySQL INSERTMySQL INSERT INTO SELECTMySQL INSERT IGNOREMySQL UPDATEMySQL UPDATE JOINMySQL DELETEMySQL ON DELETE CASCADEMySQL DELETE JOINMySQL REPLACEMySQL PREPAREMySQL 事务MySQL 表锁定MySQL USEMySQL 数据库管理MySQL CREATE DATABASEMySQL DROP DATABASEMySQL 存储引擎MySQL CREATE TABLEMySQL 序列MySQL ALTER TABLEMySQL RENAME TABLEMySQL DROP COLUMNMySQL ADD COLUMNMySQL DROP TABLEMySQL 临时表MySQL TRUNCATE TABLEMySQL 数据类型MySQL NOT NULLMySQL Primary KeyMySQL Foreign KeyMySQL UNIQUEMySQL CHECKMySQL 字符集MySQL 排序规则MySQL 导入 CSVMySQL 导出 CSVMySQL 自然排序MySQL 基础

MySQL 存储过程

MySQL 存储过程介绍MySQL 存储过程实例MySQL 存储过程变量MySQL 存储过程参数MySQL 存储过程返回多值MySQL IF 语句MySQL CASE 语句MySQL IF CASE 选择MySQL 存储过程循环MySQL 存储过程游标MySQL 存储过程列表MySQL 存储过程异常处理MySQL SIGNAL 和 RESIGNALMySQL 存储函数

MySQL 视图

MySQL 视图教程SQL 视图介绍MySQL 视图介绍MySQL 创建视图MySQL 可更新视图WITH CHECK OPTIONLOCAL&CASCADEDMySQL 视图管理

MySQL 触发器

MySQL 触发器SQL 触发器MySQL 触发器介绍MySQL 触发器的创建MySQL 创建多个触发器MySQL 触发器管理MySQL 计划事件MySQL事件修改

MySQL 索引

MySQL 索引MySQL 索引创建MySQL 索引删除MySQL 显示索引MySQL 唯一索引MySQL 前缀索引MySQL 隐形索引MySQL 降序索引MySQL 复合索引MySQL 聚集索引MySQL 索引基数MySQL USE INDEXMySQL 强制索引

MySQL 管理

MySQL 管理MySQL访问控制系统MySQL 用户创建MySQL 用户密码MySQL 权限授予MySQL 权限撤销MySQL 角色MySQL 删除用户MySQL 表维护mysqldump 备份工具MySQL 数据库列表MySQL 表列表MySQL 表字段列表MySQL 用户列表MySQL 进程列表MySQL 列生成比较MySQL中同一表中的连续行

MySQL 全文搜索

MySQL 全文搜索MySQL 全文搜索介绍FULLTEXT索引MySQL 自然语言全文搜索MySQL 布尔全文搜索MySQL查询扩展MySQL ngram

MySQL 高级

MySQL 函数MySQL 窗口函数

MySQL 技巧

MySQL 查找重复数据MySQL 删除重复数据MySQL UUIDMySQL 表的复制MySQL 复制库MySQL 变量MySQL SELECT INTO 变量MySQL 表的存储引擎MySQL 使用正则查询MySQL 添加序号MySQL 随机查询MySQL 查询第 N 高记录MySQL 重置自增值MySQL VS MariaDBMySQL 间隔值MySQL 获取当天日期MySQL NULL 映射MySQL 注释理解MySQL EXPLAINMySQL 技巧介绍MySQL COUNTMySQL 数据分层MySQL 两表比较Mysql Like 优化

MySQL 窗口函数

MySQL CUME_DIST() 函数MySQL DENSE_RANK() 函数MySQL FIRST_VALUE 函数MySQL LAG() 函数MySQL LAST_VALUE() 函数MySQL LEAD 函数MySQL NTH_VALUE 函数MySQL NTILE 函数MySQL PERCENT_RANK 函数MySQL RANK 函数MySQL ROW_NUMBER 函数

MySQL 应用

MySQL应用程序编程接口PHP MySQL教程PHP 数据库连接

MySQL 优化

mysqld 内存持续变高


MySQL 事务


简介:在本教程中,您将了解  MySQL事务 以及如何使用COMMITROLLBACK语句来管理MySQL中的事务。


介绍MySQL事务

要了解MySQL中的事务,让我们看一下在示例数据库中添加新销售订单。添加销售订单的步骤如下所述:

  1. orders表中查询最新的销售订单编号,并使用下一个销售订单编号作为新的销售订单编号。
  2. orders表中插入新的销售订单 。
  3. 获取新插入的销售订单号
  4. 将新的销售订单项目与销售订单编号一起插入 orderdetails 表格中
  5. 从两个表ordersorderdetails表中选择数据  以确认更改

现在,想象一下如果上面的一个或多个步骤由于某些原因(例如表锁定)而失败,销售订单数据会发生什么?例如,如果将订单项添加到orderdetails表中的步骤失败,则您将有一个空的销售订单。

这就是交易处理拯救的原因。MySQL事务允许您执行一组MySQL操作,以确保数据库永远不会包含部分操作的结果。在一组操作中,如果其中一个操作失败,则会发生回滚以将数据库还原到其原始状态。如果没有发生错误,则将整个语句集提交给数据库。


MySQL事务声明

MySQL为我们提供了以下控制事务的重要声明:

  • 要启动事务,请使用START TRANSACTION  语句。也可以使用START TRANSACTION的别名BEGIN或  BEGIN WORK
  • 要提交当前事务并使其永久更改,请使用COMMIT语句。
  • 要回滚当前事务并取消其更改,请使用ROLLBACK语句。
  • 要禁用或启用当前事务的自动提交模式,请使用SET autocommit语句。

默认情况下,MySQL会自动将更改永久提交到数据库。要强制MySQL不自动提交更改,请使用以下语句:

SET autocommit = 0;

或者

SET autocommit = OFF

您可以使用以下语句显式启用自动提交模式:

SET autocommit = 1;

或者

SET autocommit = ON;

MySQL事务示例

我们将使用示例数据库中的  ordersand orderDetails表进行演示。

COMMIT示例

为了使用事务,首先必须将SQL语句分解为逻辑部分,并确定何时应提交或回滚数据。

以下说明了创建新销售订单的步骤:

  1. 使用START TRANSACTION  语句启动事务  。
  2. orders表中选择最新的销售订单编号,并使用下一个销售订单编号作为新的销售订单编号。
  3. orders表格中插入新的销售订单  。
  4. 将销售订单项插入  orderdetails表中。
  5. 使用COMMIT语句提交事务  。

(可选)您可以从两个表ordersorderdetails表中选择数据  以检查新的销售订单。

以下是执行上述步骤的脚本:

-- 1. 开始一个新手事物
START TRANSACTION;
 
-- 2. 获取最新的订单编号
SELECT 
    @orderNumber:=MAX(orderNUmber)+1
FROM
    orders;
 
-- 3. 向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 INTO orderdetails(orderNumber,
                         productCode,
                         quantityOrdered,
                         priceEach,
                         orderLineNumber)
VALUES(@orderNumber,'S18_1749', 30, '136', 1),
      (@orderNumber,'S18_2248', 50, '55.09', 2); 
      
-- 5. 提交事实
COMMIT;

运行结果:

+----------------------------------+
| @orderNumber:=MAX(orderNUmber)+1 |
+----------------------------------+
|                            10426 |
+----------------------------------+
1 row in set (0.02 sec)

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

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;

这是输出:

+-------------+------------+--------------+-------------+------------+----------+----------------+-----------------+-------------+-----------------+-----------+
| orderNumber | orderDate  | requiredDate | shippedDate | status     | comments | customerNumber | orderLineNumber | productCode | quantityOrdered | priceEach |
+-------------+------------+--------------+-------------+------------+----------+----------------+-----------------+-------------+-----------------+-----------+
|       10426 | 2005-05-31 | 2005-06-10   | 2005-06-11  | In Process | NULL     |            145 |               1 | S18_1749    |              30 |    136.00 |
|       10426 | 2005-05-31 | 2005-06-10   | 2005-06-11  | In Process | NULL     |            145 |               2 | S18_2248    |              50 |     55.09 |
+-------------+------------+--------------+-------------+------------+----------+----------------+-----------------+-------------+-----------------+-----------+
2 rows in set (0.01 sec)

ROLLBACK实例

首先,登录MySQL数据库服务器并从订单表中删除数据:

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)

从输出中可以清楚地看到,更改已经回滚。

在本教程中,您学习了如何使的MySQL事务语句包含START TRANSACTION COMMI,ROLLBACK管理事务 。