数据库的隔离级别及实现原理

ACID
原子性(Atomic):在同一项业务处理过程中,事务保证了对多个数据的修改,要么同时成功,要么同时被撤销。
隔离性(Isolation):在不同的业务处理过程中,事务保证了各自业务正在读、写的数据互相独立,不会彼此影响。
持久性(Durability):事务应当保证所有成功被提交的数据修改都能够正确地被持久化,不丢失数据。
**一致性(Consistency)**数据库中的各数据是服务预期的,个数据之间不互相矛盾的。
一致性是目的,另外三个是实现一致性的手段/方法。

**

如何实现原子性和持久性

**
1、数据只有写入磁盘等硬件存储才真正拥有持久性,在内存中如果断电等数据就会丢失。
2、因为写入磁盘的操作除了“以写入”、“未写入”,还存在“正在写”的状态,因为“正在写”时程序崩溃或服务器断电等不可避免,所以不做额外操作直接写入是无法保证原子性和持久性。
3、eg:一个事务操作需要修改三个表中的数据,那么可能存在:
3.1、事务已经提交,但是在第一个数据写入磁盘成功以后服务崩溃,重启后无法找到第二第三个数据,不能保证持久性
3.2、事务未提交,第一个数据写入磁盘后崩溃,重启后第一个数据无法恢复到写入前的状态,不能保证原子性
4、一种初始的方法是通过commit logging(提交日志)来实现:在事务提交前先将数据的更改信息(包括原数据,新数据,位置等等)以顺序追加(顺序追加效率高)的形式写入commit logging日志文件中,然后提交事物,事物提交后再将commit loggin中的数据变更写入磁盘,然后 在commit logging 末尾插入end record,表示写入磁盘完成。在这期间即使服务崩溃,依然可以通过commit logging找回变更的数据。
5、commit logging 有一个缺陷:性能问题。数据必须在commit logging写入成功后才能真正写入磁盘,不允许提前写入,即使IO空闲。
6、为了解决commit logging问题,ARIES 提出了“Write-Ahead Logging”的日志改进方案,所谓“提前写入”(Write-Ahead),就是允许在事务提交之前,提前写入变动数据的意思。
7、ARIES引入了undo log(回滚日志) 和redo log(重做日志)。在变更数据写入磁盘前,必须先写入undo log(包括修改了哪个数据,修改前的值,修改后的值等信息)。
**

实现隔离性

事务的隔离性主要通过三把锁来实现:
1、读锁(read lock):共享锁,多个事务可以同时在一个数据加读锁,加了读锁以后就不能在加写锁。
2、写锁 (write lock):同一时间只有一个事务能对数据加写锁,加了写锁的数据就不能再加其他写锁和读锁。
3、区间锁(rang lock也叫范围锁),指对一个区间的数据加锁,eg:select * from user where age < 18 for update; 那么其他事务就不能再插入/修改 age<18的数据。

**
1、隔离级别分为:
读未提交:T1事务能读到T2事物没有提交的修改。此时如果T2事务回滚,则发生脏读。
读已提交:T1事务只能T2事务已提交的修改,未提交的读不到。此级别避免了脏读的存在,但是会有不可重复读的问题(不可重复读:T1事务先读了id的1的记录得到age=18岁,然后T2事务将id为1的记录age改成19并提交,T1事务再次读取id=1时,age变成了19)。
可重复读:解决了读已提交级别中不可重复度问题,保证同一个事务中多次读到的数据是一致的。可重复读会有幻读问题(T1事务第一次读取age <18的记录能读到10条记录,然后T2事务增加了一条age= 17的记录,T1事务再次读age <18,读到了11条记录)。可重复读也是Mysql/InnoDB默认的隔离级别

串行化:最高隔离级别,相单于单线程执行,可以避免可重复度中的幻读问题。
2、上述四个隔离级别是通过三把锁的运用来实现的
读未提交: 此级别事务仅对数据添加写锁,并且一致持续到事务结束,因为没有读锁,这反而令它能读到其他事务加了写锁的数据。所以T1能读到T2事务正在修改的数据。
**读已提交:**此级别事务对数据添加读锁和写锁,但是读锁会在读完以后立马释放,没有贯穿整个事务周期,所以此级别有不可重复度问题,即T1读取某个数据后释放读锁,T2事务修改了数据,然后T1事务再次读取数据,两次数据不一样。
可重复读 此级别事务对数据添加读锁和写锁,且读锁贯穿整个事务周期,所以避免了不可重复读的问题,但是会有幻读的问题
串行化: 串行化比可重复读多了区间锁,解决了幻读问题。
注意:以上仅为理论解决方案,数据库厂商的实际实现要更复杂。

数据库的隔离级别与并发处理能力是自相矛盾的,也就是说隔离级别越高,并发能力就越低,所以我们要根据自己的实际需求选择合适的隔离级别。
以上四个级别可能导致的三种问题:幻读、不可重复读、脏读,其实都是一个事务T1在读数据的时候,另一个事务T2去修改数据导致的,也就是说“一个事务读+另一个事务写”的隔离问题,此类问题除了加锁,还有一种多版本并发控制(Multi-Version Concurrency Control,MVCC)目前被各数据库厂商采用。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值