零基础学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平衡性能与安全性。掌握事务的操作语法与隔离机制,是避免数据异常的重要前提。

相关推荐
一 乐1 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
1.14(java)2 小时前
SQL数据库操作:从CRUD到高级查询
数据库
Full Stack Developme3 小时前
数据库索引的原理及类型和应用场景
数据库
IDC02_FEIYA4 小时前
SQL Server 2025数据库安装图文教程(附SQL Server2025数据库下载安装包)
数据库·windows
辞砚技术录5 小时前
MySQL面试题——联合索引
数据库·面试
萧曵 丶5 小时前
MySQL 主键不推荐使用 UUID 的深层原因
数据库·mysql·索引
小北方城市网5 小时前
分布式锁实战指南:从选型到落地,避开 90% 的坑
java·数据库·redis·分布式·python·缓存
毕设十刻5 小时前
基于Vue的人事管理系统67zzz(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
TDengine (老段)7 小时前
TDengine Python 连接器入门指南
大数据·数据库·python·物联网·时序数据库·tdengine·涛思数据
萧曵 丶8 小时前
事务ACID特性详解
数据库·事务·acid