当前位置: 首页 > ai >正文

MySql基础教程:事务基础知识

目录

一、数据库事务概述

1.什么是事务?

2.事务的ACID特性

3.为什么使用事务?

二、如何使用事务

1.示例代码

1.1转账示例

1.2自动提交模式

1.3事务的保存点

2.事务的状态

3.完整示例代码

4.IF()和IF...THEN的区别

三、事务隔离级别

 1.事务隔离级别的概念

2.四种隔离级别

2.1设置不同隔离级别

3.各隔离级别的对比

3.1脏读

3.2幻读

3.3不可重复读

4.默认隔离级别

四、事务的常见分类

五、结语

一、数据库事务概述

1.什么是事务?

事务是数据库操作的最小单元,它包含一系列的操作,这些操作要么全部执行成功,要么全部失败回滚。MySQL中的事务支持确保了数据的一致性完整性

2.事务的ACID特性
  • A - 原子性(Atomicity): 事务是最小单位,不可再分。要么全部成功,要么全部失败

  • C - 一致性(Consistency): 事务执行前后,数据库必须从一个合法状态转换到另一个合法状态。遵守所有预定义的约束(主键、外键、唯一、CHECK等)。

  • I - 隔离性(Isolation): 多个并发事务执行时,彼此的操作应该是隔离的,互不干扰。防止脏读、不可重复读、幻读。主要通过锁机制MVCC(多版本并发控制) 实现(MySQL InnoDB默认实现MVCC)。

  • D - 持久性(Durability): 一旦事务提交(COMMIT),它对数据库的改变就是永久性的,即使系统故障也能恢复(通过Redo Log)。

3.为什么使用事务?
  • 保障复杂操作的数据正确性(如转账、订单库存)。

  • 应对系统故障(宕机、断电)。

  • 支持并发操作,平衡性能与数据准确性。

  • 对比: 没有事务的数据库(如某些简单KV存储或关闭事务的表引擎如MyISAM)在复杂操作或并发下容易数据混乱。MySQL的MyISAM引擎不支持事务InnoDB引擎支持

二、如何使用事务

1.示例代码
1.1转账示例

假设我们有两个账户account_a和account_b,我们需要将100元从account_a转移到account_b。   

-- 开始事务
START TRANSACTION;-- 减少 account_a 的余额
UPDATE accounts SET balance = balance - 100 WHERE id = 'account_a';-- 增加 account_b 的余额
UPDATE accounts SET balance = balance + 100 WHERE id = 'account_b';-- 提交事务
COMMIT;

如果在执行过程中发生错误,可以使用ROLLBACK回滚事务:

-- 发生错误时回滚
ROLLBACK;
1.2自动提交模式

MySQL默认是自动提交模式(autocommit=1),即每条SQL语句都会自动提交。可以通过以下命令关闭自动提交模式:

SET autocommit = 0;
1.3事务的保存点

事务的保存点允许你在事务中设置一个标记,以便在需要时回滚到该标记而不是整个事务。

-- 设置保存点
SAVEPOINT savepoint_name;-- 回滚到保存点
ROLLBACK TO SAVEPOINT savepoint_name;-- 释放保存点
RELEASE SAVEPOINT savepoint_name;
2.事务的状态

MySQL事务在其生命周期中会经历多个状态。

  • 活动的(active)

事务中的数据库操作正在执行中,此时事务的状态就是活动的。

  • 部分提交的(partially committed)

事务中的最后一个操作执行完毕(在内存中执行),对数据库的操作还没有刷新(同步)到磁盘,此时事务的状态是部分提交的。

  • 失败的(failed)

当事务处在活跃的或者部分提交的状态左右时,可能遇到了某些错误或者人为的停止当前事务,此时事务的状态是失败的。

  • 中止的(aborted)

事务失败之后,需要撤销失败事务对当前数据库造成的影响,即回滚,当回滚操作执行完毕数据库恢复到了执行事务之前的状态,此时事务的状态是中止的。

  • 提交的(committed)

当一个事务是部分提交的状态,并将对数据库的操作同步到磁盘之后,此时事务的状态是提交的。

事务的五大状态总结如下:

3.完整示例代码

事务结合存储过程实现转账示例如下:

DELIMITER $$
--创建存储过程
CREATE PROCEDURE safe_transfer(IN from_id INT, --入参IN to_id INT,IN amount DECIMAL(10,2)
)
BEGIN-- 声明变量DECLARE retry_count INT DEFAULT 0;-- mysql的捕捉sqlException机制--开始-- 可以捕捉存储过程中出现的异常DECLARE EXIT HANDLER FOR SQLEXCEPTIONBEGIN-- 出错后判断是否已经重试过IF retry_count = 0 THEN-- 第一次出错,回滚到 savepoint_startROLLBACK TO savepoint_start;-- 错误次数+1SET retry_count = retry_count + 1;-- 重新尝试执行操作CALL attempt_transfer(from_id, to_id, amount);ELSE-- 第二次失败,直接回滚整个事务ROLLBACK;END IF;END;-- mysql的捕捉sqlException机制--结束-- 开始事务START TRANSACTION;-- 设置初始保存点SAVEPOINT savepoint_start;-- 第一次尝试执行转账CALL attempt_transfer(from_id, to_id, amount);-- 提交事务COMMIT;END$$-- 辅助存储过程:实际执行转账操作
CREATE PROCEDURE attempt_transfer(IN from_id INT,IN to_id INT,IN amount DECIMAL(10,2)
)
BEGIN-- 扣款UPDATE accounts SET balance = balance - amount WHERE id = from_id;-- ROW_COUNT() 返回上一条 SQL 语句影响的行数。IF ROW_COUNT() = 0 THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '扣款失败,账户不存在或余额不足';END IF;-- 加款UPDATE accounts SET balance = balance + amount WHERE id = to_id;IF ROW_COUNT() = 0 THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '加款失败,目标账户不存在';END IF;
END$$DELIMITER ;
4.IF()和IF...THEN的区别

 IF()是mysql的一个表达式,是一个函数。

-- 如果sex = 0 则转成'男',否则转成'女'
SELECT IF(sex = 0, '男', '女') AS gender FROM users;

在事务中示例:

-- 在 UPDATE 中使用 IF()
START TRANSACTION;-- 如果余额大于 100,则扣款 100,否则不操作
UPDATE accounts
SET balance = balance - IF(balance > 100, 100, 0)
WHERE id = 1;COMMIT;-- 在 SELECT 查询中做字段转换
START TRANSACTION;SELECT id, name, IF(balance > 0, '有余额', '无余额') AS status
FROM accounts
WHERE id IN (1, 2);COMMIT;

但你不能在事务中使用 IF ... THEN 做逻辑分支控制

例如下面这样就会报错。

START TRANSACTION;IF (SELECT balance FROM accounts WHERE id = 1) > 100 THENUPDATE accounts SET balance = balance - 100 WHERE id = 1;UPDATE accounts SET balance = balance + 100 WHERE id = 2;
ELSESELECT '余额不足' AS error;
END IF;COMMIT;

流程控制语句 IF ... THEN ... END IF;只能使用在存储过程、函数或触发器内部,不允许在“顶层”sql中直接使用。

三、事务隔离级别

 1.事务隔离级别的概念

MySQL 是客户端/服务器架构,支持多个客户端同时连接,每个连接称为一个 会话(Session)。每个会话可独立发起请求,可能属于某个事务。
为了保证数据一致性,事务具有 隔离性理论上,一个事务访问某条数据时,其他事务应排队等待,直到该事务提交。
但这种方式性能差,尤其在高并发场景下。因此,数据库需要在隔离性与并发性能之间做权衡,通过不同的 事务隔离级别 来控制并发访问的行为

事务隔离级别决定了事务之间可见性的程度。不同的隔离级别会影响并发性能和数据一致性。

2.四种隔离级别

2.1设置不同隔离级别
-- 查看当前隔离级别
SELECT @@tx_isolation;-- 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL isolation_level;-- 设置会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL isolation_level;--其中isolation_level可以是以下值之一:
-- READ UNCOMMITTED 读未提交
-- READ COMMITTED   读已提交
-- REPEATABLE READ  可重复度
-- SERIALIZABLE     串行化
3.各隔离级别的对比

这里简单解释一下脏读、不可重复读、幻读。

3.1脏读

含义:一个事务读取了另一个未提交的事务写入但尚未提交的数据。

问题:如果那个事务回滚,你读到的就是“垃圾数据”或“无效数据”。

3.2幻读

含义:同一个事务中,多次执行相同的查询语句,返回的行数不同(因为其他事务插入或删除了符合条件的数据)。

问题:看起来像是“凭空多了一行”或者“少了一行”,像“幻觉”一样。

3.3不可重复读

含义:同一个事务中,多次读取同一行数据,结果却不一样(因为其他事务修改并提交了该行)。

问题:数据在事务执行期间被其他事务更新并提交,导致当前事务两次读取的结果不一致。

4.默认隔离级别

MySQL支持事务的引擎只有InnoDB,默认的隔离级别是可重复读REPEATABLE-READ,这个隔离级别可以避免脏读、幻读,默认情况下通过Next-Key Lock 机制也防止了幻读。

(注:一般情况下很少遇到会修改默认隔离级别的情况。)

四、事务的常见分类

从事务理论的角度来看,可以把事务分为以下几种类型:

  • 扁平事务(Flat Transactions)

  • 带有保存点的扁平事务(Flat Transactions with Savepoints)

  • 链事务(Chained Transactions)

  • 嵌套事务(Nested Transactions)

  • 分布式事务(Distributed Transactions

五、结语

MySQL事务是数据库操作的核心机制,确保数据的一致性和完整性。通过ACID特性(原子性、一致性、隔离性、持久性),事务提供了一种可靠的方式来处理复杂的数据库操作。

事务的使用场景广泛,从简单的转账操作到复杂的多表数据更新,都能通过事务确保操作的可靠性。合理设置隔离级别可以平衡性能和数据一致性,避免脏读、不可重复读和幻读等问题。

掌握事务的基本命令(如BEGINCOMMITROLLBACK)以及锁机制,有助于优化数据库性能并减少并发冲突。在实际开发中,应根据业务需求选择合适的事务策略,确保系统的高效与稳定。

http://www.xdnf.cn/news/13924.html

相关文章:

  • 通信安全员A,B,C证有什么区别?
  • 一文讲清网络变压器、芯片和 RJ45 之间的接线
  • WebView工作原理全解析:如何实现混合开发的无缝衔接
  • python transformers库笔记(BertTokenizerFast类)
  • 高频面试之12 HBase
  • javascript中浏览器自带的实用方法
  • 液氮罐里的重要样本老是担心安全受到损坏如何操作可以在线记录开门时间呢?
  • 使用GpuGeek训练图像分类器:从入门到精通
  • ubuntu24.04.2安装docker自动化脚本
  • React Native 性能优化实践
  • 【Linux网络编程】基于udp套接字实现的网络通信
  • 2024年06月青少年软件编程(图形化)等级考试试卷(四级)
  • 一名高级运维工程师,一台新服务器,安装windows系统后,在网络攻防(护网行动)形式下,应该怎么做安全加固?
  • Arduino入门教程:​​​​​​​2、代码基础
  • 在 cuda 基础环境中安装完整的cupy
  • Spring AI Chat Memory 指南
  • Prompt从入门到抄作业
  • 联邦算法分析:技术深度探索与实践应用
  • Linux系统权限提升篇Vulnhub辅助项目SUID权限SUDO指令版本漏洞
  • React ajax中的跨域以及代理服务器
  • python 爬虫,爬取某乎某个用户的全部内容 + 写个阅读 app,慢慢读。
  • OpenCV CUDA模块图像变形------对图像进行GPU加速的仿射变换函数warpAffine()
  • Spring Cloud Gateway + JWT 单点登录实现方案(无独立的认证服务器)
  • doris manager 安装部署 、管理已有doris集群、使用studio进行SQL查询
  • croc-文件传输工具
  • Rust 学习笔记:Stream
  • 机器学习算法_聚类KMeans算法
  • 中小企业服务器低成本的防勒索工具:RDM防勒索
  • Python实现下载监控工具:自动检测并移动下载文件
  • 金融领域LLM开源测试集