在事务期间保持数据可用 (postgresql)

Keep data available during a transaction (postgresql)

为什么我无法在使用 truncate 语句的事务中访问数据?

我虽然可以读取 table 的数据,而同一 table 上的交易是 运行。 只要您不执行截断语句,就有可能。 而且我在文档中没有发现任何反对它的内容。

这里有一个示例项目来说明这种行为,README 试图解释如何重现:https://github.com/Haelle/pg_transaction_tests

如果它不应该发生,它可能是 ? :

The documentation 状态:

TRUNCATE acquires an ACCESS EXCLUSIVE lock on each table it operates on, which blocks all other concurrent operations on the table.

这甚至会阻止 SELECT 所需的 ACCESS SHARE 锁。

这是必要的,因为 table 在该操作期间收到一个新文件(旧文件在 COMMIT 时被删除。

如果您需要一个不会阻塞并发读取器的操作,请使用(更昂贵)

DELETE FROM tablename;

这是 postgresql 特有的东西,来自 TRUNCATE documentation

TRUNCATE acquires an ACCESS EXCLUSIVE lock on each table it operates on, which blocks all other concurrent operations on the table. When RESTART IDENTITY is specified, any sequences that are to be restarted are likewise locked exclusively. If concurrent access to a table is required, then the DELETE command should be used instead.

这是您遇到的一个非常具体的用例。不确定为什么在截断事务期间需要能够访问即将被截断的 table。但是,正如注释所说:改用 delete 。在 rails 中,这意味着:.destroy_all(检查 rails 验证)或 .delete_all(不检查 rails 验证)