摘要:MySQL 提供了多种存储引擎来支持事务。

MySQL 提供了多种存储引擎来支持事务。支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 REDO 日志实现,MyISAM 存储引擎不支持事务。

拓展:任何一种数据库,都会拥有各种各样的日志,用来记录数据库的运行情况、日常操作、错误信息等,MySQL 也不例外。例如,当用户 root 登录到 MySQL 服务器,就会在日志文件里记录该用户的登录时间、执行操作等。

为了维护 MySQL 服务器,经常需要在 MySQL 数据库中进行日志操作:

  • UNDO 日志:复制事务执行前的数据,用于在事务发生异常时回滚数据。
  • REDO 日志:记录在事务执行中,每条对数据进行更新的操作,当事务提交时,该内容将被刷新到磁盘。

默认设置下,每条 SQL 语句就是一个事务,即执行 SQL 语句后自动提交。为了达到将几个操作做为一个整体的目的,需要使用 BEGIN 或 START TRANSACTION 开启一个事务,或者禁止当前会话的自动提交。

执行事务的语法和流程

SQL 使用下列语句来管理事务。

1) 开始事务

BEGIN;

START TRANSACTION;

这个语句显式地标记一个事务的起始点。

2) 提交事务

MySQL 使用下面的语句来提交事务:

COMMIT;

COMMIT 表示提交事务,即提交事务的所有操作,具体地说,就是将事务中所有对数据库的更新都写到磁盘上的物理数据库中,事务正常结束。

提交事务,意味着将事务开始以来所执行的所有数据都修改成为数据库的永久部分,因此也标志着一个事务的结束。一旦执行了该命令,将不能回滚事务。只有在所有修改都准备好提交给数据库时,才执行这一操作。

3) 回滚(撤销)事务

MySQL 使用以下语句回滚事务:

ROLLBACK;

ROLLBACK 表示撤销事务,即在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销,回滚到事务开始时的状态。这里的操作指对数据库的更新操作。

当事务执行过程中遇到错误时,使用 ROLLBACK 语句使事务回滚到起点或指定的保持点处。同时,系统将清除自事务起点或到某个保存点所做的所有的数据修改,并且释放由事务控制的资源。因此,这条语句也标志着事务的结束。

总结

BEGIN 或 START TRANSACTION 语句后面的 SQL 语句对数据库数据的更新操作都将记录在事务日志中,直至遇到 ROLLBACK 语句或 COMMIT 语句。如果事务中某一操作失败且执行了 ROLLBACK 语句,那么在开启事务语句之后所有更新的数据都能回滚到事务开始前的状态。如果事务中的所有操作都全部正确完成,并且使用了 COMMIT 语句向数据库提交更新数据,则此时的数据又处在新的一致状态。

实例演示

下面通过两个例子来演示一下 MySQL 事务的具体用法。

例1

下面模拟在张三的账户减少 500 元后,李四的账户还未增加 500 时,有其他会话访问数据表的场景。由于代码需要在两个窗口中执行,为了方便阅读,这里我们称为 A 窗口和 B 窗口。

1) 在 A 窗口中开启一个事务,并更新 mybank 数据库中 bank 表的数据,SQL 语句和运行结果如下:

mysql> USE mybank;
Database changed
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE bank SET currentMoney = currentMoney-500
-> WHERE customerName='张三';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0

2) 在 B 窗口中查询 bank 数据表中的数据,SQL 语句和运行结果如下:

mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三 | 1000.00 |
| 李四 | 1.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

从结果可以看出,虽然 A 窗口中的事务已经更改了 bank 表中的数据,但没有立即更新数据,这时其他会话读取到的仍然是更新前的数据。

3) 在 A 窗口中继续执行事务并提交事务,SQL 语句和运行结果如下:

mysql> UPDATE bank SET currentMoney = currentMoney+500
-> WHERE customerName='李四';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> COMMIT;
Query OK, 0 rows affected (0.07 sec)

4) 在 B 窗口中再次查询 bank 数据表的数据,SQL 语句和运行结果如下:

mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三 | 500.00 |
| 李四 | 501.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

在 A 窗口中执行 COMMIT 提交事务后,对数据所做的更新将一起提交,其他会话读取到的是更新后的数据。从结果可以看出张三和李四的总账户余额和转账前保持一致,这样数据从一个一致性状态更新到另一个一致性状态。

前面提到,当事务在执行中出现问题,也就是不能按正常的流程执行一个完整的事务时,可以使用 ROLLBACK 语句进行回滚,使用数据恢复到初始状态。

在例 1 中,张三的账户余额已经减少到 500 元,如果再转出 1000 元,将会出现余额为负数,因此需要回滚到原始状态。如例 2 所示。

例2

将张三的账户余额减少 1000 元,并让事务回滚,SQL 语句和运行结果如下所示:

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec) mysql> UPDATE bank SET currentMoney = currentMoney-1000 WHERE customerName='张三';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> ROLLBACK;
Query OK, 0 rows affected (0.07 sec) mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三 | 500.00 |
| 李四 | 501.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

从结果可以看出,执行事务回滚后,账户数据恢复到初始状态,即该事务执行之前的状态。

拓展

在数据库操作中,为了有效保证并发读取数据的正确性,提出了事务的隔离级别。在例 1 和例 2 的演示中,事务的隔离级别为默认隔离级别。在 MySQL 中,事务的默认隔离级别是 REPEATABLE-READ (可重读)隔离级别,即事务未结束时(未执行 COMMIT 或 ROLLBACK),其它会话只能读取到未提交数据。

注意事项

MySQL 事务是一项非常消耗资源的功能,大家在使用过程中要注意以下几点。

1) 事务尽可能简短

事务的开启到结束会在数据库管理系统中保留大量资源,以保证事务的原子性、一致性、隔离性和持久性。如果在多用户系统中,较大的事务将会占用系统的大量资源,使得系统不堪重负,会影响软件的运行性能,甚至导致系统崩溃。

2) 事务中访问的数据量尽量最少

当并发执行事务处理时,事务操作的数据量越少,事务之间对相同数据的操作就越少。

3) 查询数据时尽量不要使用事务

对数据进行浏览查询操作并不会更新数据库的数据,因此应尽量不使用事务查询数据,避免占用过量的系统资源。

4) 在事务处理过程中尽量不要出现等待用户输入的操作

在处理事务的过程中,如果需要等待用户输入数据,那么事务会长时间地占用资源,有可能造成系统阻塞。

本文分享自华为云社区《MySQL执行事务的语法和流程》,原文作者:运气男孩。

点击关注,第一时间了解华为云新鲜技术~

详解MySQL执行事务的语法和流程的更多相关文章

  1. 详解Mysql分布式事务XA(跨数据库事务)

    详解Mysql分布式事务XA(跨数据库事务) 学习了:http://blog.csdn.net/soonfly/article/details/70677138 mysql执行XA事物的时候,mysq ...

  2. 详解MySQL索引

    原文链接详解MySQL索引 索引介绍 索引是帮助MySQL高效获取数据的数据结构.在数据之外,数据库系统还维护着一个用来查找数据的数据结构,这些数据结构指向着特定的数据,可以实现高级的查找算法. 本文 ...

  3. [深入学习Web安全](5)详解MySQL注射

    [深入学习Web安全](5)详解MySQL注射 0x00 目录 0x00 目录 0x01 MySQL注射的简单介绍 0x02 对于information_schema库的研究 0x03 注射第一步—— ...

  4. Mysql常用show命令,show variables like xxx 详解,mysql运行时参数

    MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 详细: http://dev.mysql.com/doc/ ...

  5. MySQL存储过程详解 mysql 存储过程

    原文地址:MySQL存储过程详解  mysql 存储过程作者:王者佳暮 mysql存储过程详解 1.     存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储 ...

  6. MySQL数据类型 int(M) 表示什么意思?详解mysql int类型的长度值问题

    MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MySQL 的时候,我还以为 int(3) ...

  7. 【文章阅读】详解MySQL数据类型

    详解MySQL数据类型 - 五月的仓颉 - 博客园 http://www.cnblogs.com/xrq730/p/8446246.html 注:对于MySQL的数据类型做了详细的讲解,这是我看过的最 ...

  8. 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句

    本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...

  9. 详解Mysql事务隔离级别与锁机制

    一.概述 我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能 就会导致我们说的脏写. 胀读和不可重复读.幻读这些问题. 这些问题的本质都是数据库的多事务并 ...

随机推荐

  1. 【教程】IDEA创建Maven项目并整合Tomcat发布,问题解决大全

    一篇入门教程 一.创建项目并运行 参考这个视频,能顺利运行 helloworld ,本人用的 IDEA2020.2.3 .jdk11 .Tomcat9 .Maven3.6 bilibili-IDEA( ...

  2. Maven笔记之核心概念及常用命令

    Maven的核心概念 Maven是一款服务于java平台的自动化构建工具. 自动化构建工具还有:make->ant->maven->gradle       1.约定的目录  2.P ...

  3. bp VNext 入门——让ABP跑起来

    因好多群友@我说,ABP他们简单的了解了下,按照官方的教程一路下来跑不起来(倒在了入门的门口),才有了此文. 此文结合官方文档,一步一步带领大家让ABP跑起来(跨过门口). 建议大家一步一步实际动手操 ...

  4. 网站开发学习Python实现-Django项目部署-同步之前写的博客(6.2.2)

    @ 目录 1.说明 2.思路 3.代码 关于作者 1.说明 之前写的博客都在csdn和博客园中 要将博客同步到自己的博客网站中 因为都是使用markdown格式书写的,所以直接爬取上传就完事 2.思路 ...

  5. 工具-chrome相关-安装crx包及错误解决(99.3.1)

    @ 目录 1.安装教程 2.程序包无效:"CRX_HEADER_INVALID" 1.安装教程 在浏览器上输入 chrome://extensions 并且选择开发者模式 将.cr ...

  6. 企业微信JS-SDK实现会话聊天功能

    vue引入企业微信JS-SDK实现会话聊天功能 这两天在做一个对接企业微信实现会话聊天的功能, 发现企业微信文档这块儿做的不是特别详细,网上搜索也没找到特别完整的流程. 期间也踩了不少的坑, 在此进行 ...

  7. Python之复制列表

    将一个列表的数据复制到另外一个列表中. 1 a = [1,2,3] #定义列表a 2 3 b = a[:] #将列表a的切片赋值给b,也可以理解为将b的值设置为a[:] 4 5 print(a) #打 ...

  8. CI/CD自动化发版系统设计简介

    转载自:https://www.cnblogs.com/wellful/archive/2004/01/13/10604151.html 版本迭代是每一个互联网公司必须经历的,尤其是中小型公司,相信不 ...

  9. NET 5 Session、Cookie和Cache的使用

    1.Cookie public IConfiguration Configuration { get; } // This method gets called by the runtime. Use ...

  10. 【老孟Flutter】Stateful 组件的生命周期​

    老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...