详解MySQL中的事务与ACID特性
作者:蜀山剑客李沐白 发布时间:2024-01-14 21:59:38
一、介绍
事务是数据库中的一个非常重要的概念,它是指由一系列操作所组成的逻辑单位,在这个单位内,要么所有操作都成功完成,要么所有操作都不会执行。Mysql 中使用事务来保证数据的完整性和一致性,同时也是实现高并发的关键。
本文将全面详细地讲解 Mysql 中的事务,包括事务的基本概念和 ACID 特性、事务的隔离级别和具体实现方法等,并提供相应的代码示例。
二、ACID 特性
在讲解事务的具体实现方法之前,我们先来了解一下 ACID 特性。ACID 是对事务的四个特性的概括,分别为:
原子性(Atomicity):事务是一个原子操作单元,它要么全部执行成功,要么全部回滚。
一致性(Consistency):事务在执行前后,数据库中的数据必须保持一致性状态。
隔离性(Isolation):事务的执行应该与其他事务相互独立,即不会相互干扰。
持久性(Durability):事务执行成功后,所有的变更必须永久保存到数据库中。
Mysql 中默认支持 ACID 特性,并且可以通过修改数据库配置文件的方式来调整事务的隔离级别,以满足不同的业务需求。
三、事务的隔离级别
在 Mysql 中,事务支持四种隔离级别,分别为:
读未提交(read uncommitted):一个事务可以读取另一个事务未提交的数据,这种隔离级别最低,会导致脏读。
读已提交(read committed):一个事务只能读取另一个事务已经提交的数据,避免脏读问题,但可能会出现不可重复读的情况。
可重复读(repeatable read):确保同一事务内多次读取同一数据时,结果始终相同,也就是可以避免不可重复读的问题。
序列化(serializable):最高的隔离级别,强制事务串行执行,从而避免了幽灵读和不可重复读的情况,但会有较高的性能开销。
可以通过 SET TRANSACTION ISOLATION LEVEL 命令来设置当前会话的事务隔离级别,例如:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
这将设置当前会话的事务隔离级别为读已提交。
四、事务的实现方法
Mysql 中的事务是使用 BEGIN、COMMIT 和 ROLLBACK 三个命令来完成的。
1.BEGIN
BEGIN 命令用于开启一个新的事务,将当前会话标记为一个事务。例如:
BEGIN;
2. COMMIT
COMMIT 命令用于提交当前的事务,将所有变更保存到数据库中。如果一个事务被成功地提交,那么其中的所有操作都将被永久保存到数据库。例如:
COMMIT;
3. ROLLBACK
ROLLBACK 命令用于撤销当前的事务,回滚到事务开始之前的状态。如果一个事务执行失败或者出现异常,那么其中的所有操作都将被自动回滚。例如:
ROLLBACK;
下面是一个简单的 Mysql 事务示例,该事务将从 users 表中删除所有性别为女性的记录:
BEGIN;
DELETE FROM users WHERE gender = 'female';
COMMIT;
在这个示例中,先使用 BEGIN 命令开启一个新的事务,并在其中执行了一个 DELETE 操作。如果这个操作执行成功,那么就可以执行 COMMIT 命令来提交事务,否则就可以使用 ROLLBACK 命令来回滚事务。
五、事务的嵌套和保存点
Mysql 还支持事务的嵌套和保存点。
1.事务的嵌套
事务的嵌套指的是在一个事务中嵌套另一个事务,这样可以将复杂的操作分解为多个更小的操作,便于管理和维护。例如:
BEGIN;
-- 在当前事务中开启一个嵌套事务
SAVEPOINT savepoint1;
UPDATE users SET gender = 'male' WHERE id = 1;
-- 回滚到保存点,并撤销嵌套事务的变更
ROLLBACK TO SAVEPOINT savepoint1;
COMMIT;
在这个示例中,先使用 BEGIN 命令开启一个新的事务,然后使用 SAVEPOINT 命令在其中开启一个嵌套事务。在嵌套事务中执行了一个 UPDATE 操作,但是在之后使用 ROLLBACK TO 命令回滚到了保存点,撤销了嵌套事务的变更。最后使用 COMMIT 命令提交了整个事务。
2.保存点
Mysql 中的保存点用于标记一个事务中的特定位置,可以在该位置处回滚事务的部分操作或者全部操作。例如:
BEGIN;
-- 在当前事务中创建一个保存点
SAVEPOINT savepoint1;
UPDATE users SET gender = 'male' WHERE id = 1;
-- 在保存点之后创建另一个保存点
SAVEPOINT savepoint2;
UPDATE users SET gender = 'female' WHERE id = 2;
-- 回滚到第一个保存点,撤销其后的所有操作
ROLLBACK TO SAVEPOINT savepoint1;
COMMIT;
在这个示例中,先使用 BEGIN 命令开启一个新的事务,并在其中创建了两个保存点。在第一个保存点之后执行了一个 UPDATE 操作,在第二个保存点之后又执行了一个 UPDATE 操作。最后使用 ROLLBACK TO 命令回滚到了第一个保存点,撤销了第二个保存点之后的所有操作。
六、示例代码
下面是一些事务相关的示例代码,用于演示如何使用 Mysql 中的事务来保证数据的完整性和一致性。
1.开启一个新的事务并执行插入操作:
BEGIN;
INSERT INTO users (name, age, gender) VALUES ('John', 25, 'male');
INSERT INTO users (name, age, gender) VALUES ('Jane', 29, 'female');
COMMIT;
这个事务将执行两个 INSERT 操作,向 users 表中插入两条新记录。如果这个事务执行成功,那么其中的所有操作都将被永久保存到数据库。
2.开启一个新的事务并执行更新操作:
BEGIN;
UPDATE users SET gender = 'male' WHERE age > 30;
UPDATE users SET gender = 'female' WHERE age < 20;
COMMIT;
这个事务将执行两个 UPDATE 操作,将 users 表中年龄大于 30 的记录的性别修改为 male,将年龄小于 20 的记录的性别修改为 female。如果这个事务执行失败或者出现异常,那么其中的所有操作都将被自动回滚。
3.开启一个新的事务并执行删除操作:
BEGIN;
DELETE FROM users WHERE age < 18;
DELETE FROM orders WHERE user_id IN (SELECT id FROM users WHERE age < 18);
COMMIT;
这个事务将执行两个 DELETE 操作,删除 users 表中年龄小于 18 的记录和与这些记录关联的 orders 表中的所有记录。如果这个事务执行成功,那么其中的所有操作都将被永久保存到数据库。
4.在一个事务中使用嵌套事务和保存点:
BEGIN;
-- 在当前事务中创建一个保存点
SAVEPOINT savepoint1;
UPDATE users SET gender = 'male' WHERE id = 1;
-- 在保存点之后创建另一个保存点
SAVEPOINT savepoint2;
UPDATE users SET gender = 'female' WHERE id = 2;
-- 回滚到第一个保存点,撤销其后的所有操作
ROLLBACK TO SAVEPOINT savepoint1;
COMMIT;
这个事务在当前事务中创建了两个保存点,并在第一个保存点之后执行了一个 UPDATE 操作,在第二个保存点之后又执行了一个 UPDATE 操作。最后使用 ROLLBACK TO 命令回滚到了第一个保存点,撤销了第二个保存点之后的所有操作。
七、总结
Mysql 中的事务是保证数据完整性和一致性的基本方法之一,可通过 BEGIN、COMMIT 和 ROLLBACK 命令来实现事务的开启、提交和回滚。同时也支持事务的隔离级别、事务的嵌套和保存点等高级特性,以满足不同的业务需求。在应用程序中,需要根据具体的业务场景和需要选择适当的事务隔离级别和实现方式,来保证系统的稳定性和性能。
来源:https://juejin.cn/post/7236163089090969656


猜你喜欢
- 1. 下载RPM安装包, 因为安装MySQL的时候,软件会需要一依赖关系, 所以建议把所有的安装包下载下载, 再依次安装所以的RPM包。 2
- 本文为大家分享了mysql 5.6.23 安装配置教程,供大家参考,具体内容如下1 下载mysql2 安装mysql3 配置环境变量 &nb
- 最近在折腾Python Web,在测试的时候发现,本机可以正常访问,但外网无法通过公网IP访问页面。经过各种搜索,有大致三种解决方案。一、修
- 这个javascript农历日历,万年历代码网上看到的,很不错,功能齐全,值得收藏!功能介绍:动态显示当前世界各国各时区时间,显示当前农历,
- 本文针对ThinkPHP中pathinfo的两种模式、四种路径访问模式和URL重写相关知识进行了总结归纳,分享给大家便于查询和借鉴。具体归纳
- 1.在Home(你取的项目名)的config.php中添加如下配置<?phpreturn array( &nbs
- 引入Gridgrid=Grid() # 可以分别调整上下左右的位置,可以是百分比,也可以是具体像素,如pos_top="50px&
- 需求:统计列表list1中元素3的个数,并返回每个元素的索引list1 = [3, 3, 8, 9, 2, 10, 6, 2, 8, 3,
- strip()方法返回所有字符从开始及字符串的末尾(默认空格字符)被去除后的字符串的一个副本。语法以下是strip()方法的语法
- 介绍Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户
- Python 中使用线程有两种方式:函数或者用类来包装线程对象。函数式:调用 thread 模块中的start_new_thread()函数
- tensorflow在1.4版本引入了keras,封装成库。现想将keras版本的GRU代码移植到TensorFlow中,看到TensorF
- 本文实例为大家分享了python视频转彩色字符动画的具体代码,供大家参考,具体内容如下一、效果原图:转换后:效果可通过代码开头几行的参数调节
- 目录一、线程基础以及守护进程二、线程锁(互斥锁)三、线程锁(递归锁)四、死锁五、队列六、相关面试题七、判断数据是否安全八、进程池 &
- 前言return语句用于退出函数,向调用方返回一个表达式。return在不带参数的情况下(或者没有写return语句),默认返回None。N
- 问题描述由于之前在安装VSCODE的时候,没注意详细阅读提示,而且第一次安装比较随意,只是带着想试一下VSCODE才安装的,所以安装的时候漏
- 1.实现效果2.实现代码# 导入所需库from tkinter import *import randomclass main:  
- 一 前言公司同事最近在做excel相关的工作;今天来求助知识追寻者合并多个excel为一个一个工作本,原本是java操作poi太蛋疼了,笨重
- 堆排序堆是一种完全二叉树(是除了最后一层,其它每一层都被完全填充,保持所有节点都向左对齐),首先需要知道概念:最大堆问题,最大堆就是根节点比
- 一般在卸载完数据库时,大家都希望能够将注册表信息完全删干净,下面就将教您彻底删除SQL Server注册表的方法,供您参考。在卸载SQL S