Em um lock de registro o InnoDB utiliza um algoritmo chamado trava de chave seguinte. O InnoDB faz o lock de registro, assim quando ele faz uma busca ou varre a tabela, ele atribui travas compartilhadas ou exclusivas nos registros que ele encontra. Assim o bloqueio de registro é mais precisamente chamado lock de registro de índice.
A trava que o InnoDB atribui em registro de índices também
afetas as 'lacunas' antes daquele registro de índice. Se um
usuário tem uma trava compartilhada ou exclusiva no registro
R em um índice, então outro usuário não pode inserir um
novo registro de índice imediatamente antes de R na ordem do
índice. Este bloqueio de lacunas é feito para prevenir o
chamado problema de fantasma. Suponha que eu queira ler e
travar todos os filhos com identificador maior que 100 da
tabela CHILD
e atualizar alguns campos nos
registros selecionados.
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
Suponha que exista um índice na tabela
CHILD
na coluna ID
.
Nossa consulta varrerá aquele índice começando do primeiro
registro onde ID
é maior que 100. Agora,
se a trava atribuída no registro de índice não travasse
inserções feitas nas lacunas, um novo filho poderia ser
inserido na tabela. Se agora eu executasse em minha
transação
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
novamente, eu veria um novo filho no resultado que a consulta retorna. Isto é contra o princípio de isolamento das transações: uma transação deve executar sem que os dados que ele estaja lendo sejam alterados durante a transação. Se considerarmos um conjunto de registros como um item de dados, então o novo filho 'fantasma' quebrará o principio do isolamento.
Quando o InnoDB varre um índice ele também pode bloquear a
lacuna depois do último registro no índice. Assim como no
exemplo anterior: a trava atribuida pelo InnoDB irá previnir
que seja feita qualquer inserção na tabela onde
ID
seja maior que 100.
Você pode utilizar trava de chave seguinte para implementar uma verificação de unicidade em sua aplicação: se você ler os seus dados em modo compartilhado e não ver um registro que duplique o que você irá inserir, então você pode inserí-lo com segurança e saber que o trava de chave seguinte atribuida ao registro sucessor ao seu durante a leitura irá previnir que alguém insira um registro que duplique o seu neste intervalo. Assim a trava de chave seguinte permite que você 'bloqueie' a não existência de algo em sua tabela.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.