Si tu base de datos de MySQL es "InnoDB" y utilizas transacciones, cada vez que insertas, actualizas o eliminas una fila, se genera un bloqueo de los recursos involucrados mientras dure la transacción.
Por lo que si recibes el siguiente error al ejecutar tu consulta, es que se generó un "Deadlock":
Deadlock found when trying to get lock; try restarting transaction #1234
¿Qué es un "Deadlock"?
Un Deadlock (también llamado "bloqueo mutuo", "abrazo mortal", "punto muerto", etc.) sucede cuando dos o más transacciones intentan hacer bloqueos de claves en orden opuesto, por ejemplo:
consulta 1: bloquear clave(1), bloquear clave(2);
consulta 2: bloquear clave(2), bloquear clave(1);
Si ambas consultas se ejecutaran al mismo tiempo, la consulta 1 bloqueará la clave(1) y la consulta 2 bloqueará la clave(2) y cada consulta esperará a que la otra libere la clave, ocurriendo el deadlock.
Entonces, si cambias tus consultas de modo que los bloqueos ocurran en el mismo orden, es decir:
consulta 1: bloquear clave(1), bloquear clave(2);
consulta 2: bloquear clave(1), bloquear clave(2);
Sería imposible llegar a un deadlock.
Más recomendaciones para evitarlo
- Asegúrate de no tener otras consultas que bloqueen el acceso a más de una clave a la vez.
- En el caso que hagas una eliminación (DELETE), ordena tus cláusulas "WHERE" siempre en órden ascendente (ej. clave1, clave2, clave3, etc).
- Intenta siempre adquirir el bloqueo de recursos en el mismo orden, incluso en diferentes transacciones (por ejemplo, siempre la tabla A primero, luego la tabla B).
- MySQL sugiere que en caso de un deadlock, debes volver a intentar ejecutar la consulta automáticamente. Para ello, puedes agregar esa lógica en tu consulta. Por ejemplo, has 3 reintentos de la misma consulta cuando ocurra este error en particular.
- Otra razón para el deadlock puede ser la falta de índices en tu base de datos. Cuando se inserta, actualiza o elimina una fila se debe verificar las restricciones relacionales. Es decir, asegúrate de que las relaciones sean consistentes. Para hacerlo, se necesita verificar las claves foráneas en las tablas relacionadas. Es posible que se obtenga otro bloqueo que no sea el de la fila que se intenta modificar, por lo que asegúrate de tener siempre un índice en las claves foráneas (y, por supuesto, las claves primarias también), de lo contrario podría resultar en un bloqueo de tabla en lugar de un bloqueo de fila. Si se produce el bloqueo de tabla, la contención del bloqueo es mucho mayor y aumenta la probabilidad de ocurrir un deadlock.
Comentarios
0 comentarios
Inicie sesión para dejar un comentario.