Voglio sostituire l'intero contenuto di una tabella, senza influire sulle SELECT
dichiarazioni in entrata durante il processo.
Il caso d'uso è avere una tabella che memorizzi le informazioni sulla cassetta postale che vengono regolarmente estratte e che devono essere archiviate in una tabella PostgreSQL. Esistono molti client che utilizzano un'applicazione che interroga costantemente quella stessa tabella.
Normalmente, farei qualcosa del genere (pseudocodice in arrivo) ...
BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
Ma sfortunatamente la tabella non può essere letta durante questo processo; a causa del tempo necessario INSERT INTO
per il completamento. Il tavolo è bloccato.
In MySQL, avrei usato il loro RENAME TABLE
comando atomico per evitare questi problemi ...
CREATE TABLE table_new LIKE table;
INSERT INTO table_new;
RENAME TABLE table TO table_old, table_new TO table; *atomic operation*
DROP TABLE table_old;
Come ho potuto raggiungere questo obiettivo in PostgreSQL?
Ai fini di questa domanda, puoi presumere che non sto usando chiavi esterne.
TRUNCATE
comando acquisirà un blocco AccessExclusive sulla tabella, quindi nessun altro sarà in grado di leggere dalla tabella fino a quando la transazione non viene confermata o non viene ripristinata.
delete
invece truncate
sarà più lento, ma senza bloccare i lettori. Quante righe devi eliminare?
DELETE
e INSERT
sarebbe troppo lungo.