事务可见性的判断和事务隔离级别,PostgreSQL和MySQL实现上有啥区别

时间:2021-07-05 00:35:44

事务可见性(Transaction Visibility)是指在数据库事务中,一个事务提交后,其对其他事务是否可见的规则。

在 PostgreSQL 和 MySQL 中,事务可见性的实现有一些区别:

在 PostgreSQL 中,每个事务都有一个全局的可见性戳(Global Visibility Map),该戳用于记录每个页面中的行是否对于当前事务可见。在事务开始时,事务会初始化一个可见性掩码(Visibility Mask),该掩码用于记录当前事务所涉及的数据页的可见性戳的情况。在事务进行过程中,对于访问到的每个数据页,事务会检查可见性戳和可见性掩码,从而确定当前事务能否看到该数据页中的行。如果当前事务对于该数据页中的行不可见,则会执行相应的行版本控制操作(如行版本回滚),以保证事务的可重复性。

在 MySQL 中,使用多版本并发控制(Multi-Version Concurrency Control,MVCC)机制实现事务可见性。在 MVCC 中,每个事务读取到的数据行的版本号(Version)都是在事务开始时确定的。当事务提交时,数据库会将该事务所涉及到的所有数据行的版本号更新为该事务的提交版本(Commit Version)。其他事务读取到该数据行时,会根据自己的事务版本号和数据行版本号,判断当前数据行是否对于自己可见。

总的来说,PostgreSQL 和 MySQL 的事务可见性实现有一些差异,但它们都采用了行版本控制的机制,以保证事务的可重复性和数据一致性。

PostgreSQL 和 MySQL 在事务隔离级别的实现上也有一些区别。

PostgreSQL 和 MySQL 都支持四种标准的事务隔离级别:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。这些隔离级别都有不同的特点和适用场景。

在 PostgreSQL 中,隔离级别的实现是基于多版本并发控制(Multi-Version Concurrency Control,MVCC)机制的。在 MVCC 中,每个事务读取到的数据行的版本号(Version)都是在事务开始时确定的,事务提交时,数据库会将该事务所涉及到的所有数据行的版本号更新为该事务的提交版本(Commit Version)。不同的隔离级别主要体现在如何确定当前事务可见的数据行的版本号。例如,在可重复读隔离级别中,PostgreSQL 会对每个事务建立一个独立的快照,该快照用于记录事务开始时的所有数据行版本号,在事务执行期间,只能读取该快照中的数据行,而不能读取其他事务提交的新版本数据行。

在 MySQL 中,隔离级别的实现也是基于 MVCC 机制的。在 MySQL 中,每个事务也有一个独立的事务视图(Transaction View),用于记录当前事务可以读取的数据行版本号。不同的隔离级别主要体现在如何确定当前事务可见的数据行的版本号以及如何处理事务间的冲突。例如,在可重复读隔离级别中,MySQL 会为每个事务建立一个独立的快照,该快照用于记录事务开始时的所有数据行版本号,在事务执行期间,只能读取该快照中的数据行,而不能读取其他事务提交的新版本数据行。在 MySQL 中,还有一个特殊的隔离级别“读已提交(Read Committed)”,该隔离级别可以通过加锁机制实现。

总的来说,PostgreSQL 和 MySQL 在事务隔离级别的实现上都基于 MVCC 机制,但在细节方面可能有所差异,例如如何确定当前事务可见的数据行版本号、如何处理事务间的冲突等。