前段时间面试时发现对数据库隔离性的实现原理还是有点模糊,这里做下简单的整理。
隔离性(Isolation)是数据库事务特性ACID的一个重要特性之一。
它有4种级别,主要是通过对数据库加共享锁或排他锁来实现。
共享锁又叫读锁。一个事务获取数据行的共享锁,它可以读行该数据(查询)。
排他锁又叫写锁。一个事务获取数据行的排他锁,它可以更新该行数据(增删改)。
一个事务获取一行数据的共享锁,其他事务也能获取它的共享锁,但是不能获取它的排他锁。加了共享锁,其他事务能查询,但是不能增删改。
一个事务获取了一行数据的排他锁,那其他事务就不能获取它的共享锁或排他锁。加了排他锁,其他事务不能查询,也不能增删改。
4种隔离级别的实现原理
READ_UNCOMMITED
- 事务对当前读取的数据不加锁
事务1读取某行记录时,事务2能对它进行读取、更新
- 事务在更新某数据的时候,对其添加行级共享锁,直到事务结束才释放
事务1更新某行记录时:事务2能读取到它修改后的版本,即使事务1未提交;事务2不能对它进行更新,直到事务1结束。
READ_COMMITED
- 事务对当前读取数据添加行级共享锁,读完立即释放
事务1读取某行记录时:事务2也能对它进行查询、更新
- 事务对当前更新的数据添加行级排他锁, 直到事务结束才释放
事务1更新某行记录时:事务2读取到的是事务1更新前的数据,或者等事务1提交后能读到修改后的数据; 事务2不能更新它,直到事务1结束。
REPEATABLE READ
- 事务对当前读取数据添加行级共享锁,直到事务结束才释放
事务1读取某行记录:事务2可以对它进行查询,但是不能更新;(可重复读就是因为这个)
- 事务对当前更新的数据添加行级排他锁,直到事务结束才释放
事务1更新某行记录:事务2只能读取它更新之前的记录; 事务2不能更新该记录,直到事务1结束。
SERIALIZABLE
- 事务对当前读取的数据添加表级共享锁,直到事务结束才释放
事务1读取表A的数据:事务2可以对表A进行查询,但是不能更新,直到事务1结束。
- 事务对当前读取的数据添加表级排他锁,直到事务结束才释放
事务1更新表A中的数据:事务2不能读取表A中的数据,更不能进行更新,直到事务1结束。