Postgres: Выбор в пользу более слабых гарантий изоляции транзакций для одной таблицы или одного чтения?

#postgresql

Вопрос:

Я пишу веб-приложение с Postgres 13 в качестве бэкенда. Большинство запросов завернуты в транзакцию с использованием уровня SERIALIZABLE изоляции.

Для большинства вещей это отлично работает. Тем не менее, есть некоторые случаи, когда я хотел бы, чтобы некоторые чтения в транзакции имели менее строгую изоляцию.

Например, я представляю global_flags таблицу для редко изменяемых настроек, которые может использовать любой запрос:

 await sqlAsync(`BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE`);  const batchSize = await sqlAsync(  `SELECT value FROM global_flags WHERE name = 'batch_size'`);  // ... a bunch more work ...  await sqlAsync('COMMIT');  

Я немного обеспокоен тем, что, когда мы вручную вносим изменения в global_flags записи, мы можем вызвать увеличение ошибок «сбой сериализации» для транзакций в полете. Есть ли способ сказать Postgres, что мне не нужна столь сильная гарантия согласованности для чтения global_flags таблицы?

Ответ №1:

Тебе не нужно ни капельки беспокоиться.

Если одна транзакция ничего не делает, кроме изменения этого флага, а другая просто считывает таблицу (и не пытается в нее записывать!), Две транзакции будут иметь простую зависимость RW или WR друг от друга, и не будет циклов, вызывающих ошибку сериализации.