Lo primero para empezar el trabajo con SQL Server es preparar el ambiente. La instalación…
Cómo simular un deadlock en SQL Server
Para poder crear un concepto más preciso de lo que es un deadlock, primero debemos entender qué son los bloqueos en SQL Server y también comprender la definición de qué es un deadlock. Con todas estas referencias claras será más fácil que asimiles el trabajo de simular un deadlock en SQL Server.
Este tipo de errores no siempre son fáciles de detectar, sobretodo si es que no contamos con algún mecanismo de monitoreo. Esto lo veremos más adelante. Con este propósito es que trabajaremos en un ejemplo para representar cómo es que suceden estos eventos.
Iniciemos la DEMO
Si has participado de nuestras Webinar que tenemos en agenda, seguramente has visto el ejemplo del desayuno buffet y la pelea entre quién toma el pan y quién toma la mermelada. Veamos este ejemplo en código que puedes verlo completo en github.
CREATE TABLE BF_Pablo (
Id INT IDENTITY,
Product VARCHAR(16),
Quantity SMALLINT
)
GO
INSERT INTO BF_Pablo (Product, Quantity) VALUES
('Bread', 0),
('Bacon', 5),
('Juice', 2),
('Marmalade', 0),
('Cheese', 0)
GO
CREATE TABLE BF_Scarlett(
Id INT IDENTITY,
Product VARCHAR(16),
Quantity SMALLINT
)
GO
INSERT INTO BF_Scarlett(Product, Quantity) VALUES
('Bread', 0),
('Eggs', 3),
('butter', 6),
('Marmalade', 0),
('Fruit', 8)
GO
Tenemos hasta acá dos tablas creadas para que con ellas podamos simular una actualización simultánea que genere un error. Tienes a continuación un escenario que simulará dos conexiones diferentes. Copia los scripts por separado en dos ventanas.
--------------------------
/* Session A */
--------------------------
BEGIN TRAN
UPDATE BF_Pablo
SET Quantity = Quantity +1
WHERE Product = 'Bread'
UPDATE BF_Scarlett
SET Quantity = Quantity +1
WHERE Product = 'Bread'
-- ROLLBACK
--------------------------
/* Session A */
--------------------------
--------------------------
/* Session B */
--------------------------
BEGIN TRAN
UPDATE BF_Scarlett
SET Quantity = Quantity +1
WHERE Product = 'Marmalade'
UPDATE BF_Pablo
SET Quantity = Quantity +1
WHERE Product = 'Marmalade'
-- ROLLBACK
--------------------------
/* Session B */
--------------------------
Ahora sí, vamos a simular un deadlock en SQL Server
Tienes dos ventanas y lo ideal es que puedas verlas a ambas al mismo tiempo.
Lo importante que debes ver en este ejemplo es que requerimos una ejecución por partes entre la Sesión A y la Sesión B. Iniciamos con un BEGIN TRAN entre ambos para simular que la ejecución está en curso en una sesión abierta.
Empecemos de la siguiente manera.
PASO 1
En la Sesión A ejecuta el siguiente código.
BEGIN TRAN
UPDATE BF_Pablo
SET Quantity = Quantity +1
WHERE Product = 'Bread'
PASO 2
En la Sesión B ejecuta el siguiente código
BEGIN TRAN
UPDATE BF_Scarlett
SET Quantity = Quantity +1
WHERE Product = 'Marmalade'
PASO 3
Vuelve a la Sesión A y ejecuta el siguiente código
UPDATE BF_Scarlett
SET Quantity = Quantity +1
WHERE Product = 'Bread'
PASO 4
Vuelve a la Sesión B y ejecuta el siguiente código
UPDATE BF_Pablo
SET Quantity = Quantity +1
WHERE Product = 'Marmalade'
¿Está todo listo?
Seguramente se ha generado un error como el que se muestra en la imagen
Finalmente
Lo más importante es que puedas analizar el escenario, ver qué fue lo que pasó.
Cuando no tenemos un sistema de monitoreo, es complicado saber cuándo han pasado estos errores. Especialmente cuando tampoco las aplicaciones guardan un registro del evento o mandan una alerta del error.
Intenta replicar este error pero habiendo previamente utilizado nuestra herramienta de registro de eventos de deadlock.
No olvides ver también Cómo Reducir Deadlocks en SQL Server, que es lo más importante cuando enfrentas estos errores en un ambiente de Producción.