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

事务

事务

一、事务是什么

在同一个事务中一组SQL(增删改)语句,要就全部成功,要就全部失败

简单理解:一组“必须一起成功 or 一起失败”的数据库操作集合

典型场景:

-- 转账:A 给 B 转 100
UPDATE account SET balance = balance - 100 WHERE name = 'A';
UPDATE account SET balance = balance + 100 WHERE name = 'B';

如果执行到一半宕机:

  • A扣钱成功
  • B没加钱 ❌

数据就错了

所以必须用事务保证:要么两条都成功,要么两条都回滚

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

1️⃣ 原子性(Atomicity)

事务是不可分割的最小单位

即:事务的操作是一个整体,不可再分

2️⃣ 一致性(Consistency)

事务前后,数据必须保持合法状态

即:事务执行前后,数据库状态必须保持一致

3️⃣ 隔离性(Isolation)

多个事务互不干扰

即:多个事务同时执行时,彼此之间不要互相干扰

4️⃣ 持久性(Durability)

一旦提交,数据永久保存

即:事务一旦提交,结果会永久保存至数据库中

三、事务隔离级别

3.1、Read Uncommitted(读未提交)

什么都不管,性能最高,最不安全

问题 是否发生
脏读
不可重复读
幻读

3.2、Read Committed(读已提交)

只能读“已提交数据”,SQLServer 默认级别

问题 是否发生
脏读
不可重复读
幻读

3.3、Repeatable Read(可重复读)

同一事务中,读取结果保持一致,MySQL默认级别

问题 是否发生
脏读
不可重复读
幻读 ⚠(理论有,MySQL基本解决)

3.4、Serializable(串行化)

所有事务排队执行(像单线程)

问题 是否发生
脏读
不可重复读
幻读

3.5、隔离级别比较

隔离级别 脏读 不可重复读 幻读 并发性能 实现机制
READ UNCOMMITTED 可能 可能 可能 最高 无锁
READ COMMITTED 避免 可能 可能 共享锁(默认)/行版本(RCSI)
REPEATABLE READ 避免 避免 不可能 共享锁保持到事务结束
SERIALIZABLE 避免 避免 避免 范围锁

四、三大并发问题

1️⃣ 脏读(Dirty Read)

读到了“未提交”的数据

场景:

-- 事务A
UPDATE account SET balance = 0 WHERE id = 1;  -- 还没提交-- 事务B
SELECT balance FROM account WHERE id = 1;  -- 读到了 0

如果 A 回滚:ROLLBACK; B 读到的数据就是“脏数据”

2️⃣ 不可重复读(Non-repeatable Read)

同一事务,多次读取同一数据,结果不一致

场景:

-- 事务A
SELECT balance FROM account WHERE id = 1;  -- 100-- 事务B
UPDATE account SET balance = 200 WHERE id = 1;
COMMIT;-- 事务A 再查
SELECT balance FROM account WHERE id = 1;  -- 200

前后两次结果不一样

3️⃣ 幻读(Phantom Read)

同一事务,两次查询“记录数量”不一致

场景:

-- 事务A
SELECT * FROM orders WHERE price > 100;  -- 3条-- 事务B
INSERT INTO orders VALUES (..., 150);
COMMIT;-- 事务A 再查
SELECT * FROM orders WHERE price > 100;  -- 4条 

“凭空多了一条记录”

五、事务基础使用

5.1、显式事务

BEGIN TRANSACTION [transaction_name]-- SQL语句INSERT INTO Table1 VALUES (...)UPDATE Table2 SET ...-- 更多操作
-- 提交事务
COMMIT TRANSACTION [transaction_name]
-- 或
-- 回滚事务
ROLLBACK TRANSACTION [transaction_name]

5.2、隐式事务

-- 开启事务
SET IMPLICIT_TRANSACTIONS ON
-- 执行SQL语句会自动开始事务
-- 必须显式提交或回滚
COMMIT
-- 或
ROLLBACK
-- 关闭事务
SET IMPLICIT_TRANSACTIONS OFF

代码示例:

-- 事务控制
-- 定义一个int类型的@myerror变量
DECLARE @myerror INT
-- 给变量赋值
SET @myerror = 0
BEGIN TRANSACTION -- 开启事务UPDATE bank SET umoney -= 2000 WHERE uname = 'zhangsan';set @myerror = @myerror + @@error    -- @error 错误代码 UPDATE bank SET umoney += 2000 WHERE uname = 'lisi';SET @myerror = @myerror + @@errorIF @myerror <> 0  -- 发生错误BEGINROLLBACK TRANSACTION  -- 回滚事务PRINT '转账失败'ENDELSEBEGIN-- 提交事务COMMIT TRANSACTIONPRINT '转账成功'END

5.3、ADO.NET 中的事务处理

ADO.NET中提供了SqlTransaction 来进行SQLServer的事务控制

步骤:

  1. 开启事务:连接对象.BeginTransaction()
  2. 代码没有异常,提交事务: SqlTransactionCommit() 提交事务
  3. 有异常,在catch捕获,回滚事务:SqlTransactionRollback() 回滚事务
  static void Main(string[] args){using (SqlConnection con = new SqlConnection("Server=localhost;Database=test1db;User Id=sa;Password=123456")){con.Open();//事务的隔离机制:IsolationLevel.Serializable 最高级的事务处理机制,读写都不能并发//SqlTransaction transaction = con.BeginTransaction(IsolationLevel.Serializable);//开启事务SqlTransaction transaction = con.BeginTransaction();try{using (SqlCommand comB = new SqlCommand()){comB.Connection = con;comB.Transaction = transaction;comB.CommandText = "UPDATE bank SET umoney += 2000 WHERE uname = 'lisi'";comB.ExecuteNonQuery();}using (SqlCommand comA = new SqlCommand()){comA.Connection = con;comA.Transaction = transaction;comA.CommandText = "UPDATE bank SET umoney -= 2000 WHERE uname = 'zhangsan'";comA.ExecuteNonQuery();}transaction.Commit(); //提交事务}catch (Exception ex) // 捕获异常{transaction.Rollback(); //回滚事务Console.WriteLine(ex.Message);}}}
http://www.jsqmd.com/news/513440/

相关文章:

  • 超越基础标注:DarkLabel在跨模态数据集构建中的创新实践
  • 别再重启应用了!一个Electron全局快捷键配置,搞定生产环境调试、全屏、刷新(支持Electron 28+)
  • YOLOv11网络结构拆解:从Anchor生成到损失计算的保姆级图解
  • ESP32异步MQTT客户端:QoS2/SSL/WSS全协议支持
  • 【MySQL知识点问答题】RPM 包、Linux 安装方式及助手程序
  • 树莓派+Livox Mid360避障机器人DIY指南:从点云处理到运动控制全流程
  • java-SpringBoot-线程池配置-压力测试(理论版)
  • Tao-8k代码审查实战:自动发现潜在缺陷与安全漏洞
  • 音频设备管理工具效率革命:无缝切换体验指南
  • 《爬虫对抗:ZLibrary反爬机制实战分析》
  • 用FDTD算法仿真超透镜:探索光学世界的新视角
  • HUNYUAN-MT 7B翻译终端Win11右键菜单集成:快速翻译选中文本
  • 无锡市智能体应用开发源头公司在模型训练、工具链与私有化部署上的实践特点
  • 单细胞测序宝藏:扎实的教学视频与代码分享
  • Qwen3-32B-Chat API服务部署案例:Python调用/v1/chat/completions接口详解
  • 小悦智险:保险全链路智能运营平台
  • OpenClaw硬件加速方案:QwQ-32B模型在M系列MacGPU优化
  • 2026年大健康包装定制厂家推荐:钙片包装盒/高端健康礼盒/企业礼品定制专业供应商 - 品牌推荐官
  • 低成本玩转AI:Qwen3-0.6B本地化部署实践
  • 深度强化学习驱动的混合RIS辅助ISAC系统波束成形设计
  • Qwen3.5-9B企业落地:物流单据图像理解+运单信息结构化提取
  • 实际运行的资产和设备管理系统平台源码(Java)
  • 光伏发电、电池储能与Simulink仿真:MPPT(增量导纳法)与双向buck/boost电路
  • 别再为PBR贴图转换头疼了!Photoshop/SP手把手教你Metal/Roughness与Spec/Gloss互转(附PS动作文件)
  • 锂电池 MEKF 算法实现动力电池参数与状态多尺度联合估计:文献复现之旅
  • 嵌入式Linux多线程CPU占用精确定位方法
  • 单片机控制220V交流通断:可控硅替代继电器的工程实践
  • Qwen-Image-2512-SDNQ WebUI实战教程:自定义宽高比+种子复现+下载自动化
  • WebStorm插件避坑指南:3步实现微信小程序API智能提示(2023实测版)
  • GraphicsDisplay嵌入式图形显示基类详解