Em primeiro lugar, os deadlocks não dependem de locks explícitos. O LOCK TABLE do MySQL ou o uso de modos de isolamento de transação não padrão NÃO precisam ter um deadlock. Você ainda pode ter deadlocks se nunca usar uma transação explícita.
Deadlocks podem acontecer em uma única mesa, com bastante facilidade. Mais comumente é de uma única mesa quente.
Os impasses podem até acontecer se todas as suas transações fizerem apenas uma inserção de linha única.
Um impasse pode acontecer se você tiver
- Mais de uma conexão com o banco de dados (obviamente)
- Qualquer operação que envolva internamente mais de um bloqueio.
O que não é óbvio é que, na maioria das vezes, uma única inserção ou atualização de linha envolve mais de um bloqueio. A razão para isso é que os índices secundários também precisam ser bloqueados durante as inserções/atualizações.
SELECTs não serão bloqueados (supondo que você esteja usando o modo de isolamento padrão e não esteja usando FOR UPDATE) então eles não podem ser a causa.
SHOW ENGINE INNODB STATUS é seu amigo. Ele lhe dará um monte de informações (reconhecidamente muito confusas) sobre deadlocks, especificamente, o mais recente.
- Você não pode eliminar completamente os deadlocks, eles continuarão a acontecer na produção (mesmo em sistemas de teste, se os estressar adequadamente)
- Aponte para uma quantidade muito baixa de deadlocks. Se 1% de suas transações travarem, talvez seja demais.
- Considere alterar o nível de isolamento de suas transações para read-committed SE VOCÊ ENTENDE TOTALMENTE AS IMPLICAÇÕES
- certifique-se de que seu software lide com os impasses adequadamente.