Я хочу заменить все содержимое таблицы, не влияя ни на какие входящие 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
будет слишком долго.