事务隔离模式
SQL 标准描述了数据库事务并发运行时可能出现的三种现象: 脏读——一个事务可以从另一个并发事务中读取未提交的数据。 不可重复读取——在一个事务中读取两次的行可能会发生更改,因为另一个并发事务在事务开始后提交了更改。 幻读——在同一个事务中运行两次的查询可以返回两组不同的行,因为另一个并发事务添加了行。
SQL 标准定义了数据库系统可以支持的四个事务隔离级别,以及每个级别的事务并发运行时允许的现象。 Greenplum 数据库 READ UNCOMMITTED 和 READ COMMITTED 隔离模式的行为类似于 SQL 标准的 READ COMMITTED 模式。 Greenplum 数据库 SERIALIZABLE 和 REPEATABLE READ 隔离模式的行为类似于 SQL 标准的 READ COMMITTED 模式,除了 Greenplum 数据库还防止幻读。 READ COMMITTED 和 REPEATABLE READ 的区别在于,在 READ COMMITTED 中,事务中的每个语句只能看到在语句开始之前提交的行,而在 READ COMMITTED 模式下,事务中的语句只能看到在事务开始之前提交的行。 使用 READ COMMITTED 隔离模式,如果另一个并发事务自事务开始以来已提交更改,则在事务中检索两次的行中的值可能会有所不同。 READ COMMITTED 模式还允许幻读,其中在同一个事务中运行两次的查询可以返回两组不同的行。 REPEATABLE READ 隔离模式可防止不可重复读和幻读,尽管标准不要求后者。尝试修改由另一个并发事务修改的数据的事务将回滚。在 REPEATABLE READ 模式下运行事务的应用程序必须准备好处理由于序列化错误而失败的事务。如果应用程序不需要 REPEATABLE READ 隔离模式,则好使用 READ COMMITTED 模式。 SERIALIZABLE 模式,Greenplum 数据库不完全支持,保证一组事务并发运行产生相同的结果,就好像事务一个接一个地顺序运行一样。如果指定了 SERIALIZABLE,Greenplum 数据库会回退到 REPEATABLE READ。 MVCC 快照隔离 (SI) 模型可以防止脏读、不可重复读和幻读,而无需昂贵的锁定,但是在 Greenplum 数据库中的某些 SERIALIZABLE 事务之间可能会发生其他交互,从而阻止它们真正可序列化。这些异常通常可以归因于 Greenplum 数据库不执行谓词锁定这一事实,这意味着一个事务中的写入可能会影响另一个并发事务中先前读取的结果。
注意:PostgreSQL 9.1 SERIALIZABLE 隔离级别引入了新的 Serializable Snapshot Isolation (SSI) 模型,该模型完全符合可序列化事务的 SQL 标准定义。此模型在 Greenplum 数据库中不可用。 SSI 监视并发事务以查找可能导致序列化异常的条件。当发现潜在的序列化问题时,允许提交一个事务,其他事务回滚并且必须重试。 应该检查并发运行的 Greenplum 数据库事务以识别可能同时更新相同数据的交互。通过使用显式表锁或要求冲突事务更新为表示冲突而引入的虚拟行,可以防止发现的问题。 SQL SET TRANSACTION ISOLATION LEVEL 语句设置当前事务的隔离模式。该模式必须在任何 SELECT、INSERT、DELETE、UPDATE 或 COPY 语句之前设置。