Одновременное обновление поля массива в Postgres

#arrays #postgresql #concurrency

#массивы #postgresql #параллелизм

Вопрос:

У меня есть массив, который я могу обновить у нескольких рабочих следующим образом: UPDATE my_table SET arr = array_append(my_table.arr, element) .

Проблема возникает, когда два работника пытаются обновить массив одновременно. Например, оба рабочих элемента видят, что на момент обновления массив пуст, и пытаются добавить элемент следующим образом: array_append(empty_arr, element_a) и array_append(empty_arr, element_b) . В конце концов, конечным содержимым массива будет: arr[element_a] или arr[element_b] потому, что один из рабочих завершит обновление массива раньше, и его значение будет перезаписано значением другого рабочего. Как я могу гарантировать, что оба значения записаны в массив: arr[element_a, element_b] ?

Комментарии:

1. Я думаю, вы здесь чего-то не договариваете. Это не похоже на нормальное поведение уровней транзакций PostgreSQL. Вы можете проверить это самостоятельно с помощью двух подключений psql и BEGIN … ОБНОВЛЕНИЕ и удержание ФИКСАЦИИ / ОТКАТА в одном терминале.

2. Да, если два обновления происходят одновременно, postgres сделает все правильно. Прочитайте это: postgresql.org/docs/9.5/transaction-iso.html

3. Нет, вы правы. Запрос, который я использую, это => INSERT INTO conversations (id, org_id, numeric_id, tags) SELECT id, org_id, csid, array[name] as tag FROM tags_v2 WHERE id = 'foo' ON CONFLICT(id) DO UPDATE SET tags = array_append(conversations.tags, 'append me'); Когда я тестирую его, как предложил @RichardHuxton, у меня не возникает никаких проблем… Так что, возможно, проблема не в SQL. Возможно, мне придется искать что-то еще. Спасибо за помощь, это было очень полезно.