【MySQL技术内幕】7.3-事务控制语句

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 【MySQL技术内幕】7.3-事务控制语句

在 MySQL命令行的默认设置下,事务都是自动提交(auto commit)的,即执行SQL语句后就会马上执行 COMMIT操作。因此要显式地开启一个事务需使用命令BEGIN、 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,禁用当前会话的自动提交。每个数据库厂商自动提交的设置都不相同,每个DBA或开发人员需要非常明白这一点,这对之后的SQL编程会有非凡的意义,因此用户不能以之前的经验来判断 MySQL数据库的运行方式。在具体介绍其含义之前,先来看看用户可以使用哪些事务控制语句。

  • START TRANSACTION| BEGIN:显式地开启一个事务。
  • COMMIT:要想使用这个语句的最简形式,只需发出 COMMIT。也可以更详细些,写为 COMMIT WORK,不过这二者几乎是等价的。 COMMIT会提交事务,并使得已对数据库做的所有修改成为永久性的。
  • ROLLBACK:要想使用这个语句的最简形式,只需发出 ROLLBACK。同样地,也可以写为 ROLLBACK WORK,但是二者几乎是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • SAVEPOINT identifier: SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT。
  • RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有一个保存点执行这句语句时,会抛出一个异常。
  • ROLLBACK TO [SAVEPOINT] identifier:这个语句与 SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。例如可以发出两条 UPDATE语句,后面跟一个 SAVEPOINT,然后又是两条 DELETE语句。如果执行 DELETE语句期间出现了某种异常情况,并且捕获到这个异常,同时发出了 ROLLBACK TO SAVEPOINT命令,事务就会回滚到指定的 SAVEPOINT,撤
  • 销 DELETE完成的所有工作,而 UPDATE语句完成的工作不受影响。
  • SET TRANSACTION:这个语句用来设置事务的隔离级别。 InnoDB存储引擎提供的事务隔离级别有: READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、 SERIALIZABLE。

START TRANSACTION、BEGN语句都可以在 MySQL命令行下显式地开启一事务。但是在存储过程中, MySQL数据库的分析器会自动将BEGN识别为 BEGIN…END,因此在存储过程中只能使用 START TRANSACTION语句来开启一个事务。

COMMIT和 COMMIT WORK语句基本是一致的,都是用来提交事务。不同之处在于 COMMIT WORK用来控制事务结束后的行为是CHAN还是 RELEASE的。如果是CHAIN方式,那么事务就变成了链事务。

用户可以通过参数 completion_type来进行控制,该参数默认为0,表示没有任何操作。在这种设置下 COMMIT和 COMMIT WORK是完全等价的。当参数 completion_type的值为1时, COMMIT WORK等同于 COMMIT AND CHAIN,表示马上自动开启个相同隔离级别的事务,如

mysql> create table t(a int primary key);
Query OK, 0 rows affected (1.18 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.05 sec)
mysql> set @@completion_type=1;
Query OK, 0 rows affected (0.06 sec)
mysql> begin;
Query OK, 0 rows affected (0.07 sec)
mysql> insert into t select 1;
Query OK, 1 row affected (0.12 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> commit work;
Query OK, 0 rows affected (0.08 sec)
mysql> insert into t select 2;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> insert into t select 2;
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> rollback;
Query OK, 0 rows affected (0.09 sec)
mysql> select * from t;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.05 sec)复制代码

在这个示例中我们设置 completion_type为1,第一次通过 COMMIT WORK来插入1这个记录。之后插入记录2时我们并没有用 BEGIN(或者 START TRANSACTION)来显式地开启一个事务,之后再插入一条重复的记录2就会抛出异常。接着执行ROLLBACK操作,最后发现只有1这一个记录,2并没有被插入。因为 completion_type为1时, COMMIT WORK会自动开启一个链事务,第二条 INSERT INTO t SELECT 2语句是在同一个事务内的,因此回滚后2这条记录并没有被插入表t中。

参数 completion_type为2时, COMMIT WORK等同于 COMMIT AND RELEASE。在事务提交后会自动断开与服务器的连接,如:

mysql> set @@completion_type=2;
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t select 3;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> commit work;
Query OK, 0 rows affected (0.06 sec)
mysql> select @@version;
ERROR 2013 (HY000): Lost connection to MySQL server during query复制代码

通过上面的示例可以发现,当将参数 completion type设置为2时, COMMIT WORK后用户再执行语句 SELECT @@version会出现ERROR 2013 (HY000): Lost connection to MySQL server during query的错误。抛出该异常的原因是当前会话已经在上次执行 COMMIT WORK语句后与服务器断开了连接。

ROLLBACK和 ROLLBACK WORK与 COMMIT和 COMMIT WORK的工作一样,这里不再进行赘述。

SAVEPOINT记录了一个保存点,可以通过 ROLLBACK TO SAVEPOINT来回滚到某个保存点,但是如果回滚到一个不存在的保存点,会抛出异常:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> rollback to savepoint t1;
ERROR 1305 (42000): SAVEPOINT t1 does not exist复制代码

InnoDB存储引擎中的事务都是原子的,这说明下述两种情况:构成事务的每条语句都会提交(成为永久),或者所有语句都回滚。这种保护还延伸到单个的语句。一条语句要么完全成功,要么完全回滚(注意,这里说的是语句回滚)。因此一条语句失败并抛出异常时,并不会导致先前已经执行的语句自动回滚。所有的执行都会得到保留,必须由用户自己来决定是否对其进行提交或回滚的操作。如

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t select 4;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> insert into t select 4;
ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'
mysql> select * from t;
+---+
| a |
+---+
| 1 |
| 3 |
| 4 |
+---+
3 rows in set (0.00 sec)复制代码

可以看到,插入第二记录1时,因为重复的关系抛出了1062的错误,但是数据库并没有进行自动回滚,这时事务仍需要用户显式地运行 COMMIT或 ROLLBACK命令。

另一个容易犯的错误是 ROLLBACK TO SAVEPOINT,虽然有 ROLLBACK,但其并不是真正地结束一个事务,因此即使执行了ROLLBACK TO SAVEPOINT,之后也需要显式地运行 COMMIT或 ROLLBACK命令。

mysql> truncate t;
Query OK, 0 rows affected (0.34 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t select 1;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> savepoint t1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t select 2;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> savepoint t2;
Query OK, 0 rows affected (0.00 sec)
mysql> release savepoint t1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t select 2;
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> rollback to savepoint t2;
ERROR 1305 (42000): SAVEPOINT t2 does not exist
mysql> select * from t;
+---+
| a |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.06 sec)
mysql> select * from t;
Empty set (0.00 sec)复制代码

可以看到,在上面的例子中,虽然在发生重复错误后用户通过 ROLLBACK TO SAVEPOINT2命令回滚到了保存点t2,但是事务此时没有结束。再运行命令ROLLBACK后,事务才会完整地回滚。这里再一次提醒, ROLLBACK TO SAVEPOINT命令并不真正地结束事务。



相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
15天前
|
SQL 关系型数据库 MySQL
MySQL事务日志-Undo Log工作原理分析
事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。
MySQL事务日志-Undo Log工作原理分析
|
24天前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
30天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(04)事务隔离级别、AICD、CAP、BASE原则一直搞不懂? | 看这篇就够了
本文详细介绍了数据库事务的四大特性(AICD原则),包括原子性、隔离性、一致性和持久性,并深入探讨了事务并发问题与隔离级别。同时,文章还讲解了分布式系统中的CAP理论及其不可能三角关系,以及BASE原则在分布式系统设计中的应用。通过具体案例和图解,帮助读者理解事务处理的核心概念和最佳实践,为应对相关技术面试提供了全面的知识准备。
|
1月前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
3月前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
141 43
|
2月前
|
关系型数据库 MySQL
mysql事务特性
原子性:一个事务内的操作统一成功或失败 一致性:事务前后的数据总量不变 隔离性:事务与事务之间相互不影响 持久性:事务一旦提交发生的改变不可逆
|
3月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1778 14
MySQL事务日志-Redo Log工作原理分析
|
2月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
2月前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
188 3
|
2月前
|
关系型数据库 MySQL 数据库
MySQL事务隔离级别及默认隔离级别的设置
在数据库系统中,事务隔离级别是一个关键的概念,它决定了事务在并发执行时如何相互隔离。MySQL提供了四种事务隔离级别,每种级别都解决了不同的并发问题。本文将详细介绍这些隔离级别以及MySQL的默认隔离级别。