面试题答案
一键面试1. 读未提交(Read Uncommitted)
- 读写锁协同工作:
- 读操作:不使用锁,直接读取数据。因为读未提交允许读取未提交的数据,所以无需获取锁来保证数据的一致性。
- 写操作:写操作会获取排它锁(X锁),防止其他事务同时写。
- 对数据库一致性和并发性能的影响:
- 一致性:数据一致性最差,存在脏读问题,即一个事务可以读取到另一个未提交事务修改的数据。如果未提交事务回滚,那么读取到的数据就是无效的。
- 并发性能:并发性能最高,因为读操作无需等待锁,读写操作不会相互阻塞。
- 数据一致性问题及解决方案:
- 问题:脏读。例如,事务A修改了某条数据但未提交,事务B此时读取到了该未提交的数据,若事务A回滚,事务B读取的数据就是脏数据。
- 解决方案:提高事务隔离级别到读已提交。
2. 读已提交(Read Committed)
- 读写锁协同工作:
- 读操作:读取数据时获取共享锁(S锁),读完即释放。这确保了在读取数据时,数据不会被其他事务修改。
- 写操作:写操作获取排它锁(X锁),直到事务结束才释放。
- 对数据库一致性和并发性能的影响:
- 一致性:解决了脏读问题,只能读取已提交的数据。但存在不可重复读问题,即同一事务内多次读取同一数据,可能得到不同结果,因为其他事务可能在两次读取之间修改并提交了数据。
- 并发性能:并发性能较高,读写操作相互阻塞的时间较短,读锁读完即释放。
- 数据一致性问题及解决方案:
- 问题:不可重复读。例如,事务A第一次读取某数据,事务B随后修改并提交了该数据,事务A再次读取时得到不同结果。
- 解决方案:提高事务隔离级别到可重复读。
3. 可重复读(Repeatable Read)
- 读写锁协同工作:
- 读操作:读取数据时获取共享锁(S锁),并在事务结束前不释放。这保证了在事务内多次读取同一数据时,数据不会被其他事务修改。
- 写操作:写操作获取排它锁(X锁),直到事务结束才释放。同时,对于可能影响到当前事务读取数据的写操作(如对读取范围内数据的修改),会等待当前事务结束。
- 对数据库一致性和并发性能的影响:
- 一致性:解决了脏读和不可重复读问题,但存在幻读问题。幻读指的是在一个事务内多次执行相同的查询,每次得到的结果集不一样,因为其他事务在两次查询之间插入或删除了符合查询条件的数据。
- 并发性能:并发性能适中,由于读锁持有时间较长,会增加写操作的等待时间。
- 数据一致性问题及解决方案:
- 问题:幻读。例如,事务A查询符合某条件的数据,事务B插入了符合该条件的新数据,事务A再次查询时得到了不同的结果集。
- 解决方案:提高事务隔离级别到串行化,或者在某些数据库中,通过MVCC(多版本并发控制)结合间隙锁(Next-Key Lock)来解决幻读问题。
4. 串行化(Serializable)
- 读写锁协同工作:
- 读操作:获取共享锁(S锁),直到事务结束才释放。
- 写操作:获取排它锁(X锁),直到事务结束才释放。所有事务串行执行,读写操作完全相互阻塞。
- 对数据库一致性和并发性能的影响:
- 一致性:数据一致性最高,不存在脏读、不可重复读和幻读问题。
- 并发性能:并发性能最低,因为所有事务串行执行,读写操作相互阻塞严重。
- 数据一致性问题及解决方案:
- 问题:并发性能极低,可能导致大量事务等待。
- 解决方案:在对一致性要求极高,对并发性能要求不高的场景下使用,否则降低事务隔离级别。