Я хочу заменить все содержимое таблицы, не влияя ни на какие входящие SELECTоператоры во время процесса.
Вариант использования - иметь таблицу, в которой хранится информация о почтовом ящике, которая регулярно извлекается и должна храниться в таблице PostgreSQL. Многие клиенты используют приложение, которое постоянно запрашивает ту же таблицу.
Обычно я бы сделал что-то вроде (входящий псевдокод) ...
BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
Но, к сожалению, таблица не может быть прочитана во время этого процесса; из-за времени, необходимого INSERT INTOдля завершения. Стол заблокирован.
В MySQL я бы использовал их атомарную RENAME TABLEкоманду, чтобы избежать этих проблем ...
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;
Как я могу добиться этого в PostgreSQL?
Для целей этого вопроса вы можете предположить, что я не использую внешние ключи.
TRUNCATEкоманда получит блокировку AccessExclusive для таблицы, поэтому никто другой не сможет читать из таблицы, пока эта транзакция не будет зафиксирована или откатана.
deleteвместо truncateэтого будет медленнее, но без блокировки читателей. Сколько строк нужно удалить?
DELETEи INSERTбудет слишком долго.