我无法理解锁与Postgres中的交易如何交互。交易中的Postgres锁
当我运行这个(长)查询,我被高度锁定的出现感到惊讶:
BEGIN;
TRUNCATE foo;
\COPY foo FROM 'backup.txt';
COMMIT;
的为\COPY
没有提到它需要什么级别的锁,但是this post指示它只会得到一个RowExclusiveLock。但是,当我运行\COPY
在此查询:
SELECT mode, granted FROM pg_locks
WHERE relation='foo'::regclass::oid;
我得到这个:
mode granted
RowExclusiveLock true
ShareLock true
AccessExclusiveLock true
凡到底是AccessExclusiveLock来自哪里?我假设它来自TRUNCATE
,其中requires an AccessExclusiveLock。但TRUNCATE
快速完成,所以我希望锁也能很快发布。这让我有几个问题。
当通过事务中的命令获取锁定时,是否在命令末尾(事务结束之前)释放该锁定?如果是这样,为什么我会观察上述行为?如果不是,为什么不呢?实际上,由于transactions don't touch the table until the COMMIT
,为什么交易中的TRUNCATE
需要根本阻止表?
我在PG中没有在documentation中看到transactions的任何讨论。
谢谢@Laurenz!尽管如此,我仍然很难理解交易中的TRUNCATE是如何工作的。如果“'TRUNCATE'确实清空了表格”,并且“'ROLLBACK' [不]触摸表格”,那么'TRUNCATE'如何回滚? –
我也很难理解“脏读”是什么意思(我在[docs](https://www.postgresql.org/docs/current/static/transaction-iso.html)中看到它提到) ,但这可能需要自己的问题。 –
我解释了“脏读”并添加了一个链接。你是对的,当谈到'TRUNCATE'时,我的解释有点不一致。正如[在代码中所述](https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/commands/tablecmds.c;h=f97bee5b0e464265e2af103053800900f40058ff;hb=HEAD #l1214),旧表不会立即抛出,而是在提交时,所以在这种情况下,“COMMIT”并不完全触及表,而是将其删除。我会尽力在我的解释中更清楚。 –