摘要: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 事务的具体用法。

下面模拟在张三的账户减少 500 元后,李四的账户还未增加 500 时,有其他会话访问数据表的场景。由于代码需要在两个窗口中执行,为了方便阅读,这里我们称为 A 窗口和 B 窗口。在 A 窗口中开启一个事务,并更新 mybank 数据库中 bank 表的数据,SQL 语句和运行结果如下:

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

从结果可以看出,虽然 A 窗口中的事务已经更改了 bank 表中的数据,但没有立即更新数据,这时其他会话读取到的仍然是更新前的数据。在 A 窗口中继续执行事务并提交事务,SQL 语句和运行结果如下:

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

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

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

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

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

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

拓展

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

注意事项

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

1) 事务尽可能简短

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

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

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

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

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

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

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

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

详解mysql事务_详解MySQL执行事务的语法和流程相关推荐

  1. kafka mysql事务_【干货】Kafka 事务特性分析

    特性背景 消息事务是指一系列的生产.消费操作可以要么都完成,要么都失败,类似数据库的事务.这个特性在0.10.2的版本是不支持的,从0.11版本开始才支持.华为云DMS率先提供Kafka 1.1.0的 ...

  2. 古人对梦的解释_梦见古人如何解释梦意_周公解梦梦到古人如何解释梦意是什么意思_做梦梦见古人如何解释梦意好不好...

    梦见古人如何解释梦意_周公解梦梦到古人如何解释梦意是什么意思_做梦梦见古人如何解释梦意好不好以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶 ...

  3. 在linux中怎么重置mysql密码_详解如何在Linux(CentOS)下重置MySQL根(Root)密码

    本例中以CentOS6.6下修改MySQL5.1.73举例说明. 1.首先输入"service mysqld status"查看当前mysql服务状态,下图显示正在mysqld服务 ...

  4. Alibaba之MySQL宝典_阿里巴巴内部 MySQL宝典 意外流出!极致经典,堪称数据库的天花板...

    MySQL 是一个关系型数据库,使用 SQL 语言进行增删改查操作,目前属于 Oracle 旗下的产品. MySQL 数据库开源免费,能够跨平台,支持分布式,性能也不错,可以和 PHP.Java 等 ...

  5. 什么是mysql节点_什么是MySQL集群

    一.什么是MySQL集群 MySQL集群是一个无共享的(shared-nothing).分布式节点架构的存储方案,其目的是提供容错性和高性能. 数据更新使用读已提交隔离级别(read-committe ...

  6. 怎样连接mysql文件_如何连接MYSQL数据库?

    假设您的mysql数据库资料如下: MYSQL数据库名: test MYSQL帐号:public_test1 MYSQL密码:test2 免费赠送三级域名:test.u8.1358.net MYSQL ...

  7. 怎么重启网站mysql数据库_如何重启MySQL数据库服务

    服务器的启动和停止 停止:net stop mysql 启动:net start mysql -------------------------mysql mode相关问题-------------- ...

  8. mysql猎豹_猎豹网校MySQL数据库

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 猎豹网校MySQL数据库 链接:http://pan.baidu.com/s/1i3wyPjn 密码:qxhm 教程目录 第1章 了解SQL 1.1 数据 ...

  9. 深入理解mysql系列_深入理解MySQL系列之锁

    按锁思想分类 悲观锁 优点:适合在写多读少的并发环境中使用,虽然无法维持非常高的性能,但是在乐观锁无法提更好的性能前提下,可以做到数据的安全性 缺点:加锁会增加系统开销,虽然能保证数据的安全,但数据处 ...

最新文章

  1. python wait_window_pywinauto客户端自动化---窗口等待方法
  2. 视频动作识别--Convolutional Two-Stream Network Fusion for Video Action Recognition
  3. 二叉树(先序遍历)非递归
  4. 算法设计与分析——贪心算法——汽车加油问题
  5. OAuth2,JWT,Open-ID Connect和其他令人困惑的事物
  6. SecureCRT上传bash: rz: command not found
  7. spring boot / cloud (九) 使用rabbitmq消息中间件
  8. Diffie-hellman 密匙交换
  9. 基因表达谱热图的绘制
  10. 亚马逊云计算平台---------AWS(一)
  11. vue02(脚手架,部署,helloworld)
  12. C++实现凸包Graham_scan算法
  13. python实现爬虫探探_全栈 - 9 实战 爬取豆瓣电影数据
  14. 人工智能导论(2)——启发式算法(八数码问题)
  15. 荣耀路由器w831刷linux,华为荣耀WS831路由器设置的方法
  16. 【DP_区间DP专辑】
  17. 决策树(分类树)——红酒数据(分类树的八个参数,一个属性,四个接口,以及绘图所用的代码)
  18. react vue开发赋值小技巧-短路
  19. php中redis的exec()用法,Redis Exec 命令 - Redis 教程 - 自强学堂
  20. 模电三:光耦、发声器件、继电器、数码管、瞬态抑制器

热门文章

  1. php把整数拆分成数组,数组拆分处理(整数时的处理),该怎么处理
  2. 各种类型变量的定义以及赋值
  3. EFGrid ---- copy 属性
  4. Git安装后安装目录改变
  5. zynq7020安装linux图形界面,ZYNQ开发板的NFS文件系统安装 - ZYNQ7020学习
  6. python函数参数的作用是_python函数参数的不同
  7. switch注意事项与在什么情况下使用switch或if语句
  8. JSON.toJSONString 出现 {$ref: “$.deduceGridCellVoSet[0].stateFlightsBasic[0]“}
  9. Django 分页组件替换自定义分页
  10. Glusterfs(distribute) + DRBD + heartbeat + mon 实现分布式文件系统1