数据库四种隔离级别----实现方式分析

本文深入探讨了数据库的ACID特性,包括原子性、一致性、隔离性和持久性,并详细解析了四种隔离级别:未提交读、提交读、可重复读和序列化,以及它们如何解决脏读、不可重复读、丢失更新和幻读等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 最近在看文件系统的一致性----日志部分源码。因为文件系统日志与数据库(支持事务)实现一致性实现----非常相似,看到此篇博文就来转转。

数据库的ACID四个基本要素:

  1. 原子性(Atomicity)
  2. 一致性 (Consistency)
  3. 隔离性 (Isolation)
  4. 持久性 (Durability)

针对隔离性遇到问题如下:

  • 脏读(如有事务A和B,A读取了B未提交的数据)
  • 不可重复读 (如有事务A和B,A负责读取,B负责写入,A连续读的过程中B写入了一次,A前后两次读出的数据不一样)
  • 丢失更新(如有事务A和B,AB均写入数据,A写入的数据被B覆盖)
  • 幻读 (如有事务A和B,A修改了表内数据的过程中,B向表内插入了一条数据,A修改完后发现数据并没有被全部修改完)

针对这以上四种问题,产生了以下四种隔离级别(其实可以算是3种,第一种并没有处理以上问题),在此处必须介绍以下实现隔离级别的两种锁模式:

  1. 共享锁:悲观锁,共享锁也叫S锁,是一种读锁,当一个事物获得了一条数据的共享锁,其它事务也能获得该共享锁,但不能获得排他锁,表明其它事务可读,但不可写。
  2. 排它锁:悲观锁,也叫X锁,是一种写锁,当一个事务对临界区加上排它锁,其他事物就不能获得该临界区的任何锁(共享锁,排他锁)。
  • 总结一下就是共享锁保证大家可以一起读,但只能一个人写,总结一下就是共享锁保证大家可以一起读,但只能一个人写,排他锁保证只能一个人去处理数据,其他人不能读也不能写。
1. read uncommitted(未提交读):
  • 意思是在当前隔离级别下,会读取到没有提交的数据。在这种模式下,1-4的问题均解决不了,但这种模式也不是说完全没加锁。在读取时是不会加锁的,但在更新数据时,对其加行级共享锁(其他事务不能更改,但可以读取,导致脏读),事务结束时释放。这种隔离级别未处理任何以上4个问题。
  • 举例说明:
    事务A读取某行记录,事务B也能对这行记录读取更新,当事务B更新记录时,事务A读取到B修改的版本,即使事务B未提交。
    事务A和B不能同时更新(共享锁保证A获取共享锁时A能读取数据,B能获取共享锁能读,但是不能写)
2. read committed(提交读)
  • 这种隔离级别表示读取的数据是已经提交成功的,解决了脏读问题,解决方式是给写数据加行级排他锁,这样写过程无法读取,直到事务处理完毕才释放排他锁,给读的数据加行级共享锁,这样读的时候也无法写,但是一旦读完该行就释放共享锁。这种模式下虽然处理了脏读,但是并没有处理丢失更新和不可重复读的问题。
  • 举例说明:

事务A负责读,事务B负责写,A读完数据后释放共享锁,B更新数据,事务还未结束,A再读,两次得到的数据就不一样,产生不可重复读的问题。
同理,事务A获取共享锁,更新数据,然后释放共享锁,B此时获得排它锁,再更新数据,A的数据就可能被覆盖,产生更新丢失的问题。

3. reapetable read(可重复读)
  • 这种级别下可以重复的读取数据,顾名思义解决了不可重复读的问题,同时也解决了丢失更新的问题。
  • 解决方法: 给写的数据加行级排它锁,事务结束释放,给读的数据加行级共享锁,事务结束后释放。这种模式还没处理幻读问题!
  • 举例说明:

事务A负责读,事务B负责写,A读完数据后等事务结束才释放共享锁,B更新数据,直到事务结束,A再读,两次得到数据均为A第一次读到的数据,解决不可重复读的问题。

事务A负责读,只为读取的数据加行级共享锁,B在A读过程中向表单中插入新数据,A没有处理到新插入的数据,产生幻读。

serializable(序列化)
  • 实现也很简单,事务读数据则加表级共享锁,事务写数据则加表级排他锁,幻读问题也得到了解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值