Я пытаюсь вставить или обновить данные в базе данных PostgreSQL. Простейший случай - это пара ключ-значение (фактические данные более сложные, но это наименьший ясный пример)
Когда вы устанавливаете значение, я бы хотел, чтобы оно вставлялось, если ключа там нет, в противном случае обновите. К сожалению, у Postgres нет оператора вставки или обновления, поэтому я должен сам подражать ему.
Я работал с идеей: SELECT
выяснить, существует ли ключ, и затем запустить соответствующий INSERT
или UPDATE
. Теперь ясно, что это должно быть в транзакции, иначе может случиться что-то плохое.
Однако это работает не совсем так, как мне хотелось бы - я понимаю, что существуют ограничения для сериализуемых транзакций, но я не уверен, как обойти эту проблему.
Вот ситуация -
ab: => set transaction isolation level serializable;
a: => select count(1) from table where id=1; --> 0
b: => select count(1) from table where id=1; --> 0
a: => insert into table values(1); --> 1
b: => insert into table values(1); -->
ERROR: duplicate key value violates unique constraint "serial_test_pkey"
Теперь я ожидаю, что он выдаст обычное сообщение «не удалось зафиксировать из-за одновременного обновления», но я предполагаю, что поскольку вставки - это разные «строки», этого не происходит.
Есть ли простой способ обойти это?