面试题答案
一键面试1. 读 - 写冲突
- 检测机制:
- 在PostgreSQL的SSI(Serializable Snapshot Isolation)机制下,读操作不会阻塞写操作,写操作也不会阻塞读操作。读操作会基于MVCC(多版本并发控制)读取到一个一致性的快照版本的数据。每个事务在启动时,会记录当前系统中活跃事务的ID集合。
- 当写操作尝试修改数据时,它会检查即将修改的数据行上的所有版本(通过MVCC实现)。如果发现存在一个活跃事务正在读取该数据行的某个版本(根据事务ID判断),就检测到了读 - 写冲突。
- 解决机制:
- 当检测到读 - 写冲突时,PostgreSQL会根据事务的时间戳(这里时间戳代表事务启动顺序)来决定处理方式。如果写事务的时间戳比读事务的时间戳旧(即写事务先启动),那么写事务可以继续执行并提交,因为它的修改是在读取快照建立之前开始的。如果写事务的时间戳比读事务的时间戳新,写事务会被回滚,以保证读事务读取到的快照一致性。
- MVCC作用:MVCC为读操作提供了一致性的快照视图。每个数据行的多个版本允许读操作在不被写操作阻塞的情况下,读取到一个在事务启动时就确定的版本。同时,MVCC也帮助写操作检测哪些数据行正在被活跃事务读取,以便检测读 - 写冲突。
2. 写 - 读冲突
- 检测机制:
- 与读 - 写冲突检测类似,写操作在尝试修改数据时,会检查数据行的版本。如果发现有活跃读事务正在读取该数据行的某个版本,就检测到写 - 读冲突。
- 读操作本身在读取数据时,也会记录读取的数据版本以及相关事务ID等信息。如果后续有写操作尝试修改该数据,通过对比事务ID和版本信息来检测冲突。
- 解决机制:
- 同样基于事务时间戳来解决。如果写事务时间戳比读事务时间戳旧,写事务可以提交。否则,写事务回滚,以确保读事务的一致性快照不被破坏。
- MVCC作用:MVCC通过维护数据的多个版本,让写操作能够知晓当前数据是否正在被读事务访问,以及读操作能够明确自己读取的版本信息。这使得写 - 读冲突的检测和解决得以实现,保证读操作的一致性。
3. 写 - 写冲突
- 检测机制:
- 当一个写事务尝试修改数据时,它会检查即将修改的数据行的最新版本(MVCC维护数据的多个版本)。如果发现另一个活跃事务已经修改了该数据行(通过版本号和事务ID判断),就检测到写 - 写冲突。
- 另外,在SSI机制下,每个事务会记录自己访问(包括读和写)的数据对象。当提交事务时,会检查是否与其他活跃事务的访问对象存在重叠,如果存在重叠且至少有一个事务进行了写操作,也能检测到写 - 写冲突。
- 解决机制:
- 对于直接在数据行上检测到的写 - 写冲突,通常回滚时间戳较新的事务,保留时间戳较旧的事务修改,以保证事务按顺序执行。
- 对于通过访问对象重叠检测到的写 - 写冲突,同样回滚时间戳较新的事务,确保数据一致性。
- MVCC作用:MVCC通过维护数据行的多个版本,使得写事务能够快速检测到其他事务对同一数据行的修改,从而发现写 - 写冲突。同时,MVCC也辅助基于事务时间戳的冲突解决机制,确定保留哪个事务的修改。