Custom_fields atualizado simultaneamente causa que o valor se torne um array.

Parece que esse bug já foi corrigido há algum tempo, conforme mencionado neste post: Custom_fields simultaneous save with json becomes an array

Infelizmente, agora estou lidando com múltiplos endpoints sendo chamados simultaneamente, que atualizam os custom_fields do usuário ao mesmo tempo, fazendo com que os valores definidos por mim como :text se transformem em arrays.

3 endpoints chamados e definindo custom_field como array em vez de string

Alguma ajuda? Isso está bloqueando todo o meu projeto no momento…

Encontrei esse problema na versão 2.5.0.beta7 em desenvolvimento local.

Existe alguma maneira de travar o banco de dados até que os valores sejam salvos, nesse caso?

Será que este é o problema que estou enfrentando? Differences between transactions and locking - makandra dev

Observe que, quando duas transações são executadas simultaneamente em duas threads, cada thread não vê as alterações da outra transação até que elas sejam confirmadas com sucesso. No entanto, cada thread vê suas próprias alterações (esta é uma explicação simplificada; a realidade é muito mais complexa).

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

Mostra valores normais, o que me faz pensar que várias linhas foram criadas.

Isso deveria ter resolvido. Era um bug de longa data.

Sim, eu vi :frowning:

Infelizmente, agora estou enfrentando a atualização de dados sensíveis potencialmente ao mesmo tempo. Acho que isso acontece porque estou fazendo isso por meio de endpoints, mas essa é a única maneira que tenho de fazê-lo e não tenho controle sobre as chamadas. Pode ser 1 chamada, pode ser 10.

Posso tentar minimizar as chamadas do aplicativo e enviar alguns dados em lote, mas o problema é que há 2 fontes de chamadas: dispositivos móveis e serviços externos.

Dados de pagamento estão envolvidos :frowning:

Isso parece ser o comportamento existente de campos personalizados e não uma regressão. Existem algumas maneiras de corrigi-lo:

  1. Você pode adicionar um índice único no campo personalizado (nome, user_id)
  2. Você pode envolver seu código com um DistributedMutex
  3. Você pode usar um design de tabela em vez de campos personalizados

algo assim? Parece funcionar.

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

Além disso, vou alterar a lógica para executar as chamadas uma por uma, em vez de todas de uma vez, na esperança de evitar qualquer problema.

Obrigado, pessoal @eviltrout @fzngagan