事务的隔离级别
数据库的隔离级别有4种,由低到高分别为 Read uncommitted, Read committed, Repeatable read, Serializable。而且在事务并发操作中,可能会出现脏读,不可重复读,幻读。
Read uncommitted
事务B修改某个数据,但没有提交,事务A仍然可以读取事务B修改后的数据。
但是那个未提交的事务B最后选择了rollback,没有提交,数据并没有被修改,这时候事务A在读取数据就有可能出现脏读。
为了解决脏读,采用Read committed级别
Read committed
事务A想要读取数据,如果此时事务B修改该数据,那么必须等到事务B 提交之后,事务A才能读取该数据,就解决了脏读。
但是该隔离级别又会出现下面一个问题:
如果事务A首先读取了某个数据,然后事务B修改了该数据,事务A当第二次读取该数据,此时第一次读取的数据和第二次读取的数据不同,这就是不可重复读。
--不可重复读:在一个事务范围内两次相同的查询却返回了不同的数据。
为了解决该问题,采用Reaptable read等级
Repeatable read
重复读,就是事务A如果开始读取数据,就不允许其他事务对该数据进行修改操作。
Repeatable read 可以解决 不可重复读的问题,
然而不可重复读对应的是update操作,可能还会有幻读问题:幻读问题对应的是insert插入操作
Serializable 序列化
Seriablizable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读,不可重复读与幻读,但是这种事务隔离级别效率低下,一般不使用。
大多数数据库默认的事务隔离级别是Read committed, 比如 Sql Server, Oracle。 MySql的默认隔离级别是Repeatable read。
实现原理
隔离级别的实现实际上就是控制加锁的类型和释放锁时机
Read uncomitted原理
- 读数据的时候不加锁;
- 写数据时候加行级共享锁,提交时释放锁。
因为行级锁可以并发的读,而且可以保证不能同时被更改数据。
Read committed原理
- 读数据的时候加行级共享锁,读完之后释放锁;
- 写数据时候加行级独占锁,事务结束时释放。
事务T中数据被修改时加独占锁,其他事务不能访问该数据,就解决
脏读。
Repeatable read原理
- 读数据时候加行级共享锁,事务结束时释放;
- 写数据时候加行级排它锁,事务结束时释放;
事务T中读数据时候加行级共享锁,直到事务结束,其他事务都不可以去数据进行修改,解决了不可重复读的问题
Serializable原理:
- 读数据时候加表级共享锁,事务结束时释放;
- 写数据时候加表级独占锁,事务结束是释放。