详解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
猜你喜欢
- 一、 存储过程的概念,优点,语法 在写笔记之前,首先需要整理好这些概念性的东西,否则的话,就会在概念上产生陌生或者是混淆的感觉。 概念:将常
- 该代码主要是基于python实现判断指定文件夹下是否存在指定后缀的文件。代码如下:import osYour_Dir='你的文件夹/
- 最近正好在寻求一种Python的数据库ORM (Object Relational Mapper),SQLAlchemy (项目主页)这个开
- 1、简介APScheduler是一个 Python 定时任务框架,使用起来十分方便。提供了基于日期、固定时间间隔以及 crontab 类型的
- 也许光从字面上来说,版式设计中的“亲密性”似乎不太好理解,正常的情况下,我们都会把“亲密性”理解为人与人之间的关系的一种表现,事实上在版式设
- 1. document.form.item 问题 (1)现有问题:现有代码中存在许多 document.formName.item(&quo
- 前言最近助教改作业导出的成绩表格跟老师给的名单顺序不一致,脑壳一亮就用pandas写了个脚本自动吧原始导出的成绩誊写到老师给的名单中了哈哈哈
- 我在传递数据的时候老是出错,请问如何处理?不管是什么数据库,一般来说,是它所包含引号的字符串带来的问题。假设我们使用名为“strDate”的
- 本文实例讲述了python使用mailbox打印电子邮件的方法。分享给大家供大家参考。具体如下:该范例在linux下使用import mai
- python socket 聊天室import sockets = socket.socket(socket.AF_INET, socket
- 类与实例类与实例相互关联着:类是对象的定义,而实例是“真正的实物”,它存放了类中所定义的对象的具体信息。下面的示例展示了如何创建一个类:cl
- 本文实例讲述了flask框架视图函数用法。分享给大家供大家参考,具体如下:flask框架 视图函数当中 各种实用情况简单配置1 建立连接2
- 使用文中提供的代码做一个统计表每天的新增行数及新增存储空间的功能实现步骤如下:1. 创建表创建表,存储每天的表空间占用情况CREATE TA
- 如下所示:daffodil = int(input('请输入一个三位数:'))if daffodil == pow(daff
- 写这段代码的原因是昨天项目中遇到的一个问题。一同事要求 写一个效果要求鼠标掠过表格行该行颜色改变以突出显示。这个倒不难,那哥们直接为每个Tr
- 怎样才能将在表A取得的数据插入另一个表B中?(1)对于表A和表B两个表结构完全相同的话〔字段个数,相应字段的类型等等〕,可以使用 inser
- 爬虫与反爬虫,这相爱相杀的一对,简直可以写出一部壮观的斗争史。而在大数据时代,数据就是金钱,很多企业都为自己的网站运用了反爬虫机制,防止网页
- import导入包呈现灰色问题问题描述pycharm中单个py文件导入包时呈灰色,而别的文件却能正常显示,我按照CSDN博客上给的设置①右键
- 正常时间显示<SCRIPT language=javascript><!--function Ye
- 首先我们先引入requests模块import requests一、发送请求r = requests.get('https://ap