У меня есть следующий код (псевдокод, сочетание JavaScript и SQL), работающий внутри сериализуемой транзакции:
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE
const missions = select * from missions
if (missions.length) == 0 {
insert into missions values (blah)
}
COMMIT
Другими словами, I. am:
- Выбор всех строк в таблице
missions
- Проверьте, нет ли строк (из кода моего приложения)
- Создайте строку, если строк не было.
Теперь, когда я запустил приведенный выше код параллельно (скажем, 10 потоков), я увидел, что создается более 1 строки. Учитывая, что я использую сериализуемую транзакцию, не должно ли быть возможно создание более 1 строки?
С тех пор я превратил код в один запрос, например:
insert into missions
select * from possible-missions limit (1 - (select count(*) from missions))
Что работает, но я все еще не понимаю, почему мой оригинальный код не работал должным образом.
РЕДАКТИРОВАТЬ: Я создал репозиторий для воспроизведения этой проблемы: https://github.com/derekchiang/postgres-bug