关于SegmentFault:详解MySQL执行事务的语法和流程

3次阅读

共计 2302 个字符,预计需要花费 6 分钟才能阅读完成。

摘要: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 窗口。

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

  1. 在 B 窗口中查问 bank 数据表中的数据,SQL 语句和运行后果如下:

从后果能够看出,尽管 A 窗口中的事务曾经更改了 bank 表中的数据,但没有立刻更新数据,这时其余会话读取到的依然是更新前的数据。

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

  1. 在 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 执行事务的语法和流程》,原文作者:运气男孩。

点击关注,第一工夫理解华为云陈腐技术~

正文完
 0