PostgreSQL 事务级保证只读事务中的外键一致性

问题描述

应用程序A(想想导出器)需要从正在运行的 Postgresql 数据库中读取所有表的所有行。同时应用程序B(想想网络应用程序)继续进行读写。

child一个可选的 parent 外键。

我遇到了以下访问模式的问题:

  • ABEGIN TRANSACTION
  • ASELECT * FROM parent
  • BBEGIN TRANSACTION
  • BINSERT INTO parent
  • BINSERT INTO child -- has foreign key to inserted parent
  • BCOMMIT
  • ASELECT * FROM child -- I do not want to receive the inserted child here

应用程序 A 中断,因为它读取了一个 child,而它无法读取 parent。因此,我不希望 A 读取 B 插入的 child 行。

据我所知,REPEATABLE_READ 在这里并没有给我任何保证,因为我还没有读过这个事务中的 child 表。据我了解,出于同样的原因,这也不被视为幻读。

  • SERIALIZABLE 是否保证 A 不会读取新的 child 行?
  • 我是否需要借助 A 中的应用逻辑来丢弃对 child 无效引用的 parent 行?

解决方法

开始事务 A

START TRANSACTION READ ONLY ISOLATION LEVEL REPEATABLE READ;

那么该事务中的所有语句都会看到数据库的相同状态(快照),无论并发事务修改了什么。

我添加了 READ ONLY 只是因为你说 A 是,它没有必要工作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...