数据库隔离级别
脏读
数据库隔离级别为读未提交的时候,可能发生脏读。读未提交指当会话A的数据库操作尚未commit时,会话B可以读取到这个未提交的数据。而此时如果会话A因为某些原因rollback了,那么会话B读取的数据就是错误的,也就是脏读。当隔离级别提高到读已提交时,则可以避免脏读。
幻读
不可重复读的特殊场景,不可重复读主要是指在读取某条记录时发生,而幻读指的是范围。比如,会话A第一查询年龄大于18的人,发现没有数据,但当第二次进行查询时,却查询到了数据。在串行化的隔离级别下,不会发生幻读。
不可重复读
简单的理解就是多次读取结果不一致,在会话A中多次相同的操作读取的数据是不一致的。比如,在会话A的两次读取操作直接,会话B对此数据进行了提交,那么会话A第一次读取的是之前的数据,第二次读取的是之后的数据。通过隔离级别可重复读来解决这个问题。
排他锁
又称为X 锁,写锁。一个事务对数据对象 O 加了 排他锁,就可以对 O 进行读取和更新。加锁期间其它事务不能对 O 加任何锁。
共享锁
又称为S 锁,读锁。一个事务对数据对象O加了共享锁,可以对O进行读取操作,但是不能进行更新操作。加锁期间其它事务能对O 加 共享锁,但是不能加排他锁。
读已提交
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
- 写操作加排他锁
- 读操作不加瞬时共享锁,即不必等待事务结束,就释放掉的共享锁
可重复读
读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
- 写操作会加排他锁;
- 读操作不加共享锁,等待事务结束后才会释放掉共享锁;
总结
| 隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
|---|---|---|---|
| 未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
| 已提交读(Read committed) | 不可能 | 可能 | 可能 |
| 可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
| 可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
- 在InnoDB引擎中,对于索引的扫描,不仅锁住扫描到的索引,而且还锁住这些索引覆盖的范围,因此这个范围是内插入数据是不允许的。
- 使用select @@tx_isolation;
- 查询数据库的隔离级别。隔离级别越高(读未提交->读已提交->可重复读->串行化),越能保证数据的完整性和一致性,对并发性能的影响也会越大。
- Mysql默认的级别是可重复读,优先考虑把数据库系统的隔离级别设为读已提交。