目录
1.前言
为什么会出现这些奇怪的现象呢,其实是因为数据库是以事务作为基本单位处理数据的(原子性)。那么为了快速的操作,数据库会有多个线程并发执行多个事务。但是当这些事务对相同数据进行查询和修改的时候就会发生以下的问题:丢失修改,脏读,不可重复读,幻读。
2.丢失修改
当事务A和事务B同时对同一数据a进行修改,当事务A把数据修改为a1时,紧接着事务B把数据修改成a2,此时A的修改就丢失了。那么就造成了丢失修改。
3.脏读
当事务A修改了数据a为a1时,此时事务B对数据a进行了读取操作,但是事务A还没有提交。此时事务B读取的是未修改的数据。此时就出现了脏读。
4.不可重复读
就是事务A读到事务B修改后并提交的数据(update)。在同一个事务中,对于同一组数据读取到的结果不一致。比如,事务B 在 事务A 提交前读到的结果,和在 事务A 提交后读到的结果可能不同。不可重复读出现的原因就是由于事务并发修改记录而导致的。
5.幻读
当事务A读取表中数据,假如有4条,但是事务B又插入了1条,而且提交了,此时事务A再去读取,发现变成5条记录了,此时出现幻读。
6.四种隔离级别
1.读未提交(Read Uncommitted)
对应一级封锁协议
如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此数据,该隔离级别可以通过“排他写锁”,但是不排斥读操作。
解决了丢失修改
2.读已提交(Read Committed)
对应二级封锁协议
如果是一个读事务,则允许其他事务读(加S锁),如果是写事务将会禁止其他事务访问该行数据(加X锁)。
解决了丢失修改和脏读
3.可重复读(Repeatable Read)
可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括读写),这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了不可重复读和脏读,但是有时可能会出现幻读。
解决了丢失修改、脏读、不可重复读
4.串行化(Serializable)
对应三级封锁协议
提供严格的事务隔离,它要求事务串行化执行,事务只能一个接着一个地执行,但不能并发执行。
解决了丢失修改、脏读、不可重复读、幻读
7.三级封锁协议
1.一级封锁协议
是事务A修改数据a之X锁,直到事务结束才释放。
作用:
防止其丢失修改。
2.二级封锁协议
在一级封锁协议上加上事务A在读取数据a之前S锁,读完之后就释放。
作用:
防止丢失修改及读脏数据。
3.三级封锁协议
在一级封锁协议上事务A在读取数据a之前必须加S锁,事务结束之后才能释放。
作用:
防止丢失修改,读脏数据和不可重复读。
8.图示
X锁 | S锁 | 一致性保持 | |||||
---|---|---|---|---|---|---|---|
操作结束释放 | 事务结束释放 | 操作结束释放 | 事务结束释放 | 不丢失修改 | 不读脏数据 | 可重复读 | |
一级封锁协议 | Y | Y | |||||
二级封锁协议 | Y | Y | Y | Y | |||
三级封锁协议 | Y | Y | Y | Y | Y |