与使用锁和闩锁进行并发控制的 Oracle 数据库不同,Greenplum 数据库(与 PostgreSQL 一样)通过使用多版本模型(Multiversion Concurrency Control,MVCC)来维护数据一致性。这意味着在查询数据库时,每个事务都会看到数据快照,从而保护事务不会查看可能由相同数据行上的(其他)并发更新引起的不一致数据。这为每个数据库会话提供了事务隔离。简而言之,读者不会阻止作者,而作者也不会阻止读者。每个事务都会看到数据库的快照,而不是锁定表。事务隔离级别
SQL 标准定义了四个事务隔离级别。在 Greenplum 数据库中,您可以请求四种标准事务隔离级别中的任何一种。但在内部,只有两个不同的隔离级别——读提交和可序列化:
已提交读 — 当事务在此隔离级别上运行时,SELECT 查询只会看到在查询开始之前提交的数据。它永远不会看到未提交的数据或并发事务在查询执行期间提交的更改。但是,SELECT 确实会看到在其自己的事务中执行的先前更新的效果,即使它们尚未提交。实际上,SELECT 查询会在查询开始运行的那一刻看到数据库的快照。请注意,如果其他事务在第一个 SELECT 执行期间提交更改,则两个连续的 SELECT 命令可以看到不同的数据,即使它们在单个事务中也是如此。UPDATE 和 DELETE 命令在搜索目标行方面的行为与 SELECT 相同。他们只会找到在命令开始时间提交的目标行。然而,这样的目标行在被发现时可能已经被另一个并发事务更新(或删除或锁定)。读提交模式提供的部分事务隔离对于很多应用来说已经足够了,而且这种模式使用起来既快速又简单。但是,对于执行复杂查询和更新的应用程序,可能需要保证比读提交模式提供的更严格一致的数据库视图。
可序列化——这是最严格的事务隔离。此级别模拟串行事务执行,就好像事务已一个接一个地、串行地而不是同时地执行一样。由于序列化失败,使用此级别的应用程序必须准备好重试事务。当事务处于可序列化级别时,SELECT 查询只会看到事务开始之前提交的数据。它永远不会看到未提交的数据或并发事务在事务执行期间提交的更改。但是,SELECT 确实会看到在其自己的事务中执行的先前更新的效果,即使它们尚未提交。单个事务中的连续 SELECT 命令总是看到相同的数据。UPDATE 和 DELETE 命令在搜索目标行方面的行为与 SELECT 相同。他们只会找到在事务开始时提交的目标行。但是,这样的目标行在找到时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,可序列化事务将等待第一个更新事务提交或回滚(如果它仍在进行中)。如果第一个更新程序回滚,则其效果被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。这样的目标行在被发现时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,可序列化事务将等待第一个更新事务提交或回滚(如果它仍在进行中)。如果第一个更新程序回滚,则其效果被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。这样的目标行在被发现时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,可序列化事务将等待第一个更新事务提交或回滚(如果它仍在进行中)。如果第一个更新程序回滚,则其效果被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。然后它的影响被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。然后它的影响被否定,可序列化事务可以继续更新最初找到的行。但是如果第一个更新程序提交(并且实际上更新或删除了该行,而不仅仅是锁定它),那么可序列化事务将被回滚。
read uncommitted — 与 Greenplum 数据库中的已提交读一样对待。
可重复读取——在 Greenplum 数据库中被视为可序列化。
Greenplum 数据库中默认的事务隔离级别是读提交的。要更改事务的隔离级别,可以在开始事务时声明隔离级别,或者在事务启动后使用 SET TRANSACTION 命令。
在此处输入链接描述