Pergunta

Será que isso causa uma condição de corrida com o MySQL (InnoDB):

  1. Iniciar Transação.

  2. Tente obter registro.

  3. Se o registro não existe, retorno.

  4. Se o registro existe, excluí-lo e adicionar uma entrada de registro dizendo que é foi excluída.

  5. End Transaction (commit / rollback).

É possível que outro processo para começar um pouco antes da etapa de exclusão em 2b, detectar a presença do registro e, em seguida, ter ambos os processos entrar itens de entradas de exclusão para o log?

Há precauções que eu preciso para tomar?

Graças.

Foi útil?

Solução

Use 'selecionar para atualização' no passo 2. Somente um processo será capaz de obter um bloqueio na linha evitando assim o cenário que você descreveu.

Outras dicas

Journeyman programador, creio eu, tem a solução correta. Desde que você indicou que você estiver usando uma ferramenta quebrada ORM (um que não vai permitir que você consulta para atualização) Eu sugiro que você move sua inserção na tabela de log em um gatilho na operação de exclusão para que você irá evitar a duplicação entrada.

Iniciar Transação.

Excluir registro / * usando os mesmos critérios você usa para 'tentar obter registro' * /

Se a resposta indica registro foi de fato eliminado, adicione uma entrada de registo.

End Transaction (commit / rollback).

Não há mais condição de corrida.

Sim, é possível para uma outra operação para verificar a tabela depois que você lê-lo.

ainda pior, porque da forma como as transações trabalho, mesmo depois de excluir a linha, as novas operações que início verá a linha porque você ainda não se comprometeram a exclusão.

SELECT ... FOR UPDATE é uma maneira de impedi-lo.

LOCK TABLE tablename é outra.

Infelizmente, desde que você está usando um ORM, eu não poderia dizer se ele tem a capacidade de fazer qualquer um destes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top