零基础学SQL(八)——事务

SQL 事务:原理、操作与隔离机制全解析

在数据库操作中,事务是保障数据一致性的核心机制。尤其在金融转账、订单支付等关键场景,事务能避免因操作中断或错误导致的数据异常。本文将从事务定义出发,结合实操案例讲解基本操作,深入解析 ACID 特性,并梳理并发场景下的隔离级别方案。

一、事务的核心定义

事务是一组不可分割的 SQL 操作集合,它遵循 "要么全部成功,要么全部失败" 的原则。例如转账场景中,"张三账户减 1000 元" 和 "李四账户加 1000 元" 必须作为一个事务执行 ------ 若中间出现错误(如网络中断、SQL 语法错误),需撤销已执行的 "减钱" 操作,否则会导致资金凭空消失。

二、事务的基本操作与实操案例

1. 关键操作命令

操作目的 SQL 命令 说明
查看自动提交状态 SELECT @@AUTOCOMMIT; 返回 1 表示自动提交(默认),0 表示手动提交
设置自动提交方式 SET @@AUTOCOMMIT = 0; 0 为手动提交,仅对当前会话有效
提交事务 COMMIT; 确认所有操作,永久写入数据库
回滚事务 ROLLBACK; 撤销未提交的操作,恢复到事务开始前状态
手动开启事务(方式 1) START TRANSACTION; 或 BEGIN TRANSACTION; 显式开启事务,后续操作需手动提交

2. 转账场景实操对比

(1)未使用事务的风险场景

若直接执行以下 SQL,当第 2 条语句执行成功、第 3 条语句出错时,会出现 "张三钱少了但李四钱没加" 的异常:

sql 复制代码
-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三账户减1000(执行成功)
update account set money = money - 1000 where name = '张三';
-- 模拟错误(如语法错误)
update account set money = money + 1000 where name = '李四'  -- 缺少分号,执行失败
(2)使用手动提交的正确流程

通过设置@@AUTOCOMMIT = 0或START TRANSACTION开启手动事务,确保操作原子性:

sql 复制代码
-- 方式1:修改自动提交模式
SET @@AUTOCOMMIT = 0;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
COMMIT;  -- 无错误则提交,有错误则执行ROLLBACK
-- 方式2:显式开启事务(推荐)
START TRANSACTION;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
COMMIT;  -- 确认提交,若中间出错执行ROLLBACK撤销所有操作

三、事务的四大特性(ACID)

事务必须满足以下四个特性,才能确保数据可靠性:

  1. 原子性(Atomicity)

事务是不可分割的最小单元,如转账中的 "减钱" 和 "加钱" 要么同时完成,要么同时撤销,不存在中间状态。

  1. 一致性(Consistency)

事务执行前后,数据总量需保持一致。例如转账前两人总余额为 5000 元,事务结束后总余额仍需为 5000 元。

  1. 隔离性(Isolation)

多个事务并发执行时,每个事务的操作需与其他事务隔离,避免相互干扰(如 A 事务未提交的数据,B 事务无法读取)。

  1. 持久性(Durability)

事务一旦提交(COMMIT),对数据的修改将永久保存到数据库,即使后续系统崩溃也不会丢失。

四、并发事务的问题与隔离级别

当多个事务同时操作同一批数据时,可能出现三类问题,需通过 "隔离级别" 进行控制。

1. 并发事务的三大问题

问题类型 描述
脏读(Dirty Read) 事务 A 读取了事务 B 未提交的数据,若 B 后续回滚,A 读取的数据即为 "脏数据"。
不可重复读 事务 A 先后两次读取同一行数据,期间事务 B 修改并提交了该数据,导致 A 两次读取结果不同。
幻读(Phantom Read) 事务 A 按条件查询数据时无结果,但若尝试插入符合条件的数据,却发现该数据已存在(由事务 B 插入并提交)。

2. 四大隔离级别与问题规避

MySQL 默认隔离级别为Repeatable Read,不同级别对问题的规避能力和性能不同:

隔离级别 脏读 不可重复读 幻读 性能特点
Read uncommitted √ √ √ 性能最高,安全性最差
Read committed × √ √ 避免脏读,常用于 Oracle 默认
Repeatable Read(默认) × × √ 避免脏读和不可重复读
Serializable × × × 性能最低,安全性最高

注:"√" 表示该级别下会出现对应问题,"×" 表示不会出现。

3. 隔离级别的查看与设置

sql 复制代码
-- 查看当前会话隔离级别
SELECT @@TRANSACTION_ISOLATION;
-- 设置隔离级别(SESSION仅当前会话有效,GLOBAL对所有会话有效)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

五、总结

事务是数据库保障数据一致性的核心机制,其 ACID 特性是衡量事务可靠性的关键标准。在实际开发中,需根据业务场景选择合适的隔离级别 ------ 例如金融场景需用Serializable确保绝对安全,而普通查询场景可用Read committed平衡性能与安全性。掌握事务的操作语法与隔离机制,是避免数据异常的重要前提。

相关推荐
l1t5 分钟前
DeepSeek总结的有符号、无符号、未对齐:从汇编到 SQL 的教训
汇编·数据库·sql
夜雪一千11 分钟前
MySQL 如何提高查询速度:从索引、SQL、表结构到实战调优
android·sql·mysql
麦壳饼21 分钟前
SonnetDB SQL Cookbook:常用查询模式速查
数据库·sonnetdb
高级程序源39 分钟前
hive电商平台商品销售数据分析与趋势预测45659-计算机课程设计、毕业设计
vue.js·hive·spring boot·mysql·数据分析·django·课程设计
for_ever_love__1 小时前
LangChain Text-to-SQL:让不会写 SQL 的人查数据库
数据库·sql·langchain·大模型·agent·rag·问答
梦想不只是梦与想1 小时前
SQLAlchemy:查询与操作 (三)
数据库·python·sqlalchemy
Aric_Jones1 小时前
WAL / CDC / 复制槽 /位点
数据库·oracle
草莓熊Lotso2 小时前
【C++ 基于微服务的即时通讯系统】基建三件套:gflags + gtest + spdlog 源码编译安装与实战入门
linux·网络·数据库·c++·微服务·log4j
bksczm2 小时前
Redis基础篇之初识分布式
数据库·redis·分布式
for_ever_love__2 小时前
MySQL 索引类型全解:B+Tree / Hash / R-Tree / 全文 的底层差异,以及一次性建对的选型表
数据库·mysql·b+树·唯一索引·全文索引·索引类型·索引分类