Por algum motivo comercial, estou executando a consulta SELECT * FROM table WHERE updated_at > $1 AND user_id = $2;
.
Considere duas transações, A e B, que estão atualizando linhas na tabela: UPDATE table SET value = $1, updated_at = NOW() WHERE id = $2;
. A transação A começa primeiro, portanto, a updated_at
linha de A é anterior à linha de B. updated_at
No entanto, por algum motivo, A fica mais lento e B confirma primeiro.
Se a primeira consulta for executada antes de A ser confirmado, o software exibirá a linha de B, mas não a linha de A, o que as empresas dizem não ser aceitável.
Isso poderia ser resolvido usando pg_xact_commit_timestamp()
, mas retorna quando a transação foi concluída, não confirmada (provavelmente é adequado para o meu caso de uso).
Outra solução poderia ser executar as transações SELECT FROM table WHERE user_id = $1 FOR UPDATE;
antes de atualizar a linha, mas essas consultas fazem parte de transações maiores e acho que isso destruiria o desempenho de gravação.
Uma solução simples parece fazer com que a transação B espere que A seja confirmada. Existe uma maneira de conseguir isso?
Se você tiver transações maiores, usar
now()
orcurrent_timestamp
é questionável, pois essas funções retornam o timestamp da transação , obtido no início da transação do banco de dados.clock_timestamp()
, que retorna a hora atual, seria melhor. Ainda assim, uma transação confirmada primeiro pode terminar com um carimbo de data/hora posterior.Concordo que os bloqueios seriam uma solução ruim: são ruins para o desempenho e podem até causar deadlocks.
Eu questiono a exigência. Por que é importante quando a transação do banco de dados foi confirmada?
Eu acho que as "empresas" realmente não se importam quando as transações são cometidas, elas querem uma ordem confiável das transações. As transações não têm uma ordem bem definida no PostgreSQL. Tudo que você precisa é de uma ordem lógica. Eu diria que se a declaração que você mostra for a última declaração da transação, e se você usar
clock_timestamp()
, a solução é boa. Seu carimbo de data/hora define a ordem das transações. O tempo real de confirmação (que será logo depois) é irrelevante.