【问题标题】:PostgreSQL Transaction Isolation READ UNCOMMITTEDPostgreSQL 事务隔离 读未提交
【发布时间】:2015-11-11 07:33:02
【问题描述】:

我想尝试使用带有 pgadmin 的 PostgreSQL 进行事务隔离。首先,我在 BEGIN 中插入了一条新记录,但没有 COMMIT。

BEGIN;
INSERT INTO my_table(id,value) VALUES (1,'something');

//UNCOMMITTED

然后,我尝试读取未提交的数据

BEGIN TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM my_table
COMMIT;

但我找不到新记录。怎么了?

【问题讨论】:

  • Postgres 不支持read uncommittedFrom the manual: "在 PostgreSQL 中,READ UNCOMMITTED 被视为 READ COMMITTED"
  • 你为什么想要这样做?处理隔离、并发、可见性等是数据库的用途。我有时想进行调试和数据恢复,但有一些设施可以做到这一点。我真正想要READ UNCOMMITTED 的唯一一次是尝试一个排队系统,因为这种咨询锁定效果很好。

标签: postgresql transaction-isolation


【解决方案1】:

PostgreSQL 不支持脏读 (READ UNCOMMITTED)。正如@a_horse_with_no_name 所指出的,the manual 说:

SQL 标准定义了一个附加级别,READ UNCOMMITTED。在 PostgreSQL 中,READ UNCOMMITTED 被视为READ COMMITTED

这符合标准中的规则,即数据库必须将不受支持的隔离级别视为最强的支持级别。

在 PostgreSQL 中不支持从正在进行的事务中读取未提交的元组的方法。如果有的话,您将能够获得诸如主键的重复值和一般混乱之类的东西,所以无论如何它都不会很有用。

进行中的事务可以通过几种方式进行通信和相互影响:

  • 通过共享客户端应用程序(当然)
  • SEQUENCE(和 SERIAL)更新会立即发生,而不是在提交时发生
  • advisory locking
  • 正常的行和表锁定,但在 READ COMMITTED 可见性的规则内
  • UNIQUEEXCLUSION 约束

使用pageinspect 等仅限超级用户的调试工具可以查看未提交的元组数据,但前提是您真正了解数据存储的内部结构。它仅适用于数据恢复和调试。您会在十六进制输出的墙上看到多个版本的数据。

【讨论】:

    【解决方案2】:

    Lospejos,如果您开始交易并执行插入操作,您可以运行 SELECT 来查看行,因为您在交易中,其他人看不到这一行。但是如果你发出另一个 BEGIN 它是另一个事务,所以不要这样做,只需执行 (BEGIN, INSERT, SELECT, COMMIT)。如果您选择了您的行并注意到它是错误的,请执行 ROLLBACK 以丢弃该行。 Postgress 不接受 UNCOMMITED READ 的事实令人遗憾。例如,我在 DB2 和 Teradata 中使用它。特别是如果您想在不等待 COMMIT 的情况下查看其他事务在表中执行的操作。

    【讨论】:

    • Postgres 不支持脏读并不是一个“遗憾”。在我看来,其他引擎提供的 READ UNCOMMITTED 是一种克服其 ACID 实现锁定问题的技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    相关资源
    最近更新 更多