Обновление custom_fields одновременно приводит к преобразованию значения в массив

Кажется, эта ошибка была исправлена уже давно, судя по этой теме: Custom_fields simultaneous save with json becomes an array

К сожалению, сейчас я столкнулся с тем, что одновременно вызываются несколько конечных точек, которые обновляют custom_fields пользователя, из-за чего значения, которые я устанавливаю как :text, превращаются в массивы.

3 конечные точки вызываются и устанавливают custom_field в массив вместо строки

Любая помощь? Это блокирует весь мой проект прямо сейчас…

Проблема возникает в версии 2.5.0.beta7 в локальной разработке.

Есть ли способ установить блокировку на БД до сохранения значений в такой ситуации?

Может ли это быть проблемой, с которой я сталкиваюсь? Differences between transactions and locking - makandra dev

Обратите внимание, что когда две транзакции выполняются параллельно в двух потоках, каждый поток не видит изменений другой транзакции до тех пор, пока они не будут успешно зафиксированы. Однако он видит свои собственные изменения (это упрощённое объяснение, в реальности всё гораздо сложнее).

def self.cast_custom_field(key, value, types, return_array = true)

Отображает обычные значения, что заставляет меня думать, что было создано несколько строк.

Это должно было исправить проблему. Это был давний баг.

Да, я видел это :frowning:

К сожалению, теперь мне приходится обновлять конфиденциальные данные, возможно, одновременно. Я думаю, это происходит потому, что я делаю это через эндпоинты, но это единственный способ, которым я могу это сделать, и я не контролирую вызовы. Это может быть один вызов, а может быть и десять.

Я могу попытаться сократить количество вызовов из приложения и отправлять некоторые данные пакетно, но проблема в том, что есть два источника вызовов: мобильное приложение и внешние сервисы.

Затрагиваются платежные данные :frowning:

Это похоже на существующее поведение пользовательских полей, а не на регрессию. Есть несколько способов это исправить:

  1. Вы можете добавить уникальный индекс для пользовательского поля (name, user_id).
  2. Вы можете обернуть ваш код в DistributedMutex.
  3. Вы можете использовать проектирование таблиц вместо пользовательских полей.

что-то вроде этого? Похоже, работает.

DistributedMutex.synchronize("user_data_update_#{user.id}") do
    user.save_custom_fields(true)
end

Кроме того, я изменю логику так, чтобы вызовы выполнялись по очереди, а не все сразу, что, надеюсь, предотвратит любые проблемы.

Спасибо, ребята, @eviltrout @fzngagan