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

事务隔离级别详解

1. 事务并发问题

    1. 脏读(Dirty Read)

  • 定义:事务A读取了事务B未提交的数据,事务B回滚后,事务A读取的数据无效。

  • 示例

    -- 事务A
    UPDATE users SET balance = 500 WHERE id = 1; -- 未提交
    
    -- 事务B
    SELECT balance FROM users WHERE id = 1; -- 读取到500(脏数据)
    
    -- 事务A回滚后,事务B读到的数据无效。

 2.不可重复读(Non-Repeatable Read)

  • 定义:事务A多次读取同一数据,事务B在期间修改并提交了该数据,导致事务A前后读取结果不一致。

  • 示例

    -- 事务A
    SELECT balance FROM users WHERE id = 1; -- 结果为100
    
    -- 事务B
    UPDATE users SET balance = 200 WHERE id = 1; -- 提交
    
    -- 事务A再次读取
    SELECT balance FROM users WHERE id = 1; -- 结果为200(不一致)

3.幻读(Phantom Read)

  • 定义:事务A查询某个范围的数据,事务B在期间插入或删除符合该范围的数据,导致事务A两次查询结果的行数不同。

  • 示例

    -- 事务A
    SELECT * FROM users WHERE age > 18; -- 返回2行
    
    -- 事务B
    INSERT INTO users (id, age) VALUES (3, 20); -- 提交
    
    -- 事务A再次查询
    SELECT * FROM users WHERE age > 18; -- 返回3行(出现幻行)


2. 事务隔离级别

由低到高分为四个级别,解决的问题逐步严格:

隔离级别脏读不可重复读幻读实现机制性能
读未提交 (Read Uncommitted)❌ 允许❌ 允许❌ 允许无锁或读不加锁最高
读已提交 (Read Committed)✅ 避免❌ 允许❌ 允许行级共享锁(读时加锁,读完释放)
可重复读 (Repeatable Read)✅ 避免✅ 避免⚠️ 部分避免(如MySQL)快照读(MVCC) + Next-Key锁
串行化 (Serializable)✅ 避免✅ 避免✅ 避免表级锁或严格范围锁最低

3. 各隔离级别实现原理

   1.读未提交

  • 实现:不采用任何锁机制,直接读取最新数据(包括未提交的数据)。

  • 问题:所有并发问题均存在。

   2.读已提交

  • 实现(以Oracle为例):

    • 写操作:事务修改数据时加排他锁(X锁),直到事务结束。

    • 读操作:每次读取时获取共享锁(S锁),读完立即释放。

  • 示例

    -- 事务A修改数据(加X锁)
    UPDATE users SET balance = 500 WHERE id = 1;
    
    -- 事务B读取时需等待事务A释放X锁,避免脏读。

   3.可重复读

  • 实现(以MySQL的InnoDB为例):

    • MVCC(多版本并发控制):为每个事务生成数据快照,保证多次读取一致性。

    • Next-Key锁:行锁 + 间隙锁,防止其他事务在范围内插入新数据(解决幻读)。

  • 示例

    -- 事务A首次读取(生成快照)
    SELECT * FROM users WHERE age > 18; -- 返回2行
    
    -- 事务B插入新数据(被Next-Key锁阻塞)
    INSERT INTO users (id, age) VALUES (3, 20); -- 等待
    
    -- 事务A再次读取(仍为2行)
    SELECT * FROM users WHERE age > 18;

  4.串行化

  • 实现:所有操作按顺序执行,通过表级锁或严格的范围锁实现。

  • 问题:并发性能极低,仅适用于低并发场景。


4. 数据库实现差异

   1.MySQL(InnoDB引擎)

  • 默认隔离级别:可重复读(Repeatable Read)。

  • 幻读处理:通过Next-Key锁避免幻读。

   2.Oracle / PostgreSQL

  • 默认隔离级别:读已提交(Read Committed)。

  • 幻读处理:在可重复读级别下仍可能出现幻读,需升级到串行化。

   3.SQL Server

  • 默认隔离级别:读已提交(Read Committed)。

  • 支持快照隔离级别(Snapshot Isolation):类似MVCC,避免不可重复读和幻读。


5. 隔离级别设置
  1. SQL语句设置

    -- 设置当前会话的隔离级别
    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    -- 开始事务
    START TRANSACTION;

      2.JDBC连接设置(Java示例): 

Connection conn = dataSource.getConnection();
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

       3.Spring框架配置

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void updateUser() {
    // 业务逻辑
}

6. 实际应用建议
  • 读已提交:适用于多数OLTP场景,平衡性能与一致性。

  • 可重复读:需要事务内多次读取一致的场景(如对账系统)。

  • 串行化:仅用于关键数据(如金融交易),确保绝对一致。


总结:事务隔离级别通过锁机制或MVCC解决并发问题,需根据业务需求与数据库特性选择。理解不同级别的行为差异,是设计高并发系统的关键基础。


相关文章:

  • 蓝桥杯 好数【暴力、基础知识】
  • ubnetu 服务器版本常用端口和开放的端口对应的应用
  • 基于YOLOV8的中草药识别检测系统(包含数据集+PyQt5界面+系统代码)
  • [每周一更]-(第139期):从FRP认识内网穿透及反向代理
  • python的filter()、map()、reduce()函数测试
  • C 语言 - 指针与const复杂声明完全掌握 | 右左法则详解与实践指南
  • ES6变量声明:let、var、const全面解析
  • sudo snap升级报错
  • 源码编译安装Nginx
  • tensorflow-gpu==2.6对应的 transformers 版本
  • AI Agent
  • 蓝桥杯C++组部分填空题
  • 如何为C++实习做准备?
  • Samtec行业科普 | 人工智能嵌入式解决方案
  • Mitosis:跨框架的UI组件解决方案
  • Java 与 LibreOffice 集成开发指南
  • 嵌入式MCU常用模块
  • 玩转Docker | 使用Docker搭建Blog微博系统
  • 从零开始:在 GrapesJS Style Manager 中新增 row-gap 和 column-gap
  • API身份验证与密钥管理最佳实践
  • 中国有哪些b2b的企业/朝阳区搜索优化seosem
  • 适合0基础网站开发软件/商品标题优化
  • 代做设计网站好/友链交换有什么作用
  • 建设游戏网站/长沙靠谱seo优化价格
  • 南京那些公司做网站/高明搜索seo
  • 怎么建设网站后台/南宁百度推广代理商