Observar o trabalho que sobrevive ao timeout
B insere uma nota numa transação e tenta atualizar uma linha bloqueada por A. Com innodb_rollback_on_timeout=OFF, recebe 1205. A própria sessão ainda lê a nota, mas a ligação observadora não a vê. Quando B executa COMMIT, a nota torna-se visível ao observador apesar de a atualização ter falhado. Este é o risco de confirmar automaticamente num bloco finally: o motor pode ter desfeito apenas o comando, deixando trabalho anterior pendente. O laboratório usa uma nota fictícia para tornar visível a fronteira; num débito e crédito reais, essa mesma decisão exigiria preservar o contrato de negócio.
Comparar rollback explícito e opção do servidor
Noutra tentativa com a opção OFF, B responde ao timeout com ROLLBACK e a nota anterior não é confirmada. O segundo servidor descartável arranca com a opção ON: depois do mesmo erro, a nota já não é visível na própria sessão e um COMMIT posterior não a recupera. O contraste foi executado em duas instâncias separadas, sem alterar um servidor de produção. Regista o valor efetivo antes de decidir o âmbito da repetição. Mesmo quando o motor desfaz tudo, a aplicação precisa de decidir se deve repetir, com que limites e como tratar efeitos que não pertencem à transação SQL.
Cancelar uma query não termina a ligação
Depois de confirmar a relação de espera, o observador envia KILL QUERY apenas ao CONNECTION_ID de B criado pelo guião. A query devolve 1317; a ligação continua com o mesmo identificador e ainda lê a nota inserida anteriormente. O guião executa ROLLBACK e confirma que essa nota não foi persistida. A aceitação não se limita ao retorno do comando KILL, que sinaliza a interrupção sem representar a recuperação funcional inteira. Num pool real, verifica o estado e a política de reutilização depois do erro. Este ensaio não implementa o pool nem valida permissões para intervir em sessões de terceiros.
Distinguir duplicado de deadlock
Uma transação insere id 4 e tenta inserir novamente a mesma chave, sem IGNORE. O segundo comando falha com 1062; um COMMIT confirma a primeira nota. Num ensaio diferente, duas transações retêm linhas opostas e pedem o lock uma da outra. Uma recebe 1213 e perde toda a transação, incluindo a nota escrita antes do ciclo. A sobrevivente confirma ambas as atualizações e a sua nota. Não atribuas o mesmo tratamento a todos os erros nem escolhas a vítima por suposição. O código, a configuração e o âmbito efetivamente desfeito orientam a recuperação.
Repetir a unidade correta e reduzir ciclos
Após o deadlock, repetir apenas o último UPDATE da vítima pode omitir trabalho que o motor já desfez. Uma nova tentativa, quando apropriada, deve reconstruir a unidade completa com leituras atuais, limites e identidade de negócio coerente. O guião não executa essa lógica de aplicação. Executa, porém, um contraste de ordem: ambos os participantes atualizam linha 1 e depois linha 2. Um espera, o outro confirma, e ambos acabam com sucesso neste interleaving. Isso evita o ciclo concreto, sem demonstrar ausência universal de deadlocks. Mantém tratamento de erro mesmo depois de melhorar ordem, índices e duração das transações.
Converter o ensaio em critérios de aceitação
O relatório regista versão 9.7.2, cliente PyMySQL 1.2.3, configuração, diagnósticos e estados antes e depois. Os dois servidores temporários terminam, as seis ligações fecham e as quatro threads de query são recolhidas. Não há TCP, credenciais reais, réplica, crash, carga ou workshop humano. Para levar o padrão ao serviço, ensaia o driver e pool usados, o orçamento de tentativas, efeitos externos e confirmação incerta do commit. Define quem decide retomar o batch e como reconciliar operações incompletas. A revisão editorial e os testes locais são evidência útil, mas não substituem aprovação funcional nem revisão independente.
SELECT @@global.innodb_rollback_on_timeout;
SET SESSION innodb_lock_wait_timeout=1;
START TRANSACTION;
INSERT INTO notes VALUES(1,'earlier work');
-- Another owned connection holds the required row lock.
UPDATE balances SET units=80 WHERE id=1;
-- After error1205, the application decides recovery explicitly.
ROLLBACK;Um INSERT anterior ao timeout 1205 permanece pendente com rollback-on-timeout OFF e desaparece com a opção ON.
Armadilhas comuns
Assumir rollback total em qualquer erro; COMMIT em finally; repetir só o último comando após deadlock; tomar KILL QUERY como limpeza do pool.
Tópicos relacionados: Concorrência e identidade da ligação · Atomicidade e aceitação operacional
O erro não substitui o contrato de atomicidade. Confirma o âmbito desfeito, limpa a sessão e repete a unidade adequada.
Referência: InnoDB error handling · MySQL 9.7 LTS with InnoDB reference semantics