Tengo un problema de interbloqueo con dos transacciones que no tienen acceso a ningún registro común. Tampoco hay escalada de bloqueo. Entonces no puedo explicar por qué es posible un punto muerto.SqlServer 2005: problema de interbloqueo sin registros compartidos
El interbloqueo se produce cuando dos de tales transacciones se ejecutan al mismo tiempo:
begin transaction
update A set [value] = [value]
where id = 1; /* resp. 2 */
/* synchronize transactions here */
SELECT *
FROM
A inner join B on A.B_FK = B.id
inner join C on C.A_FK = A.id
WHERE
A.[value] = 1; /* resp. 2 */
rollback;
Estas son las tablas y los datos para configurar el escenario:
CREATE TABLE A (
id INT NOT NULL,
[value] INT,
B_FK INT
primary key (id)
)
CREATE TABLE B (
id INT NOT NULL,
primary key (id)
)
CREATE TABLE C (
id INT NOT NULL,
A_FK INT
primary key (id)
)
INSERT INTO A VALUES(1, 1, 1)
INSERT INTO B VALUES(1)
INSERT INTO C VALUES(1, 1)
INSERT INTO A VALUES(2, 2, 2)
INSERT INTO B VALUES(2)
INSERT INTO C VALUES(2, 2)
Tabla A
está en el medio de tres tablas Si cambio algo en la consulta, por ejemplo, elimine una de las tablas unidas B
o C
, no hay interbloqueo. Lo mismo cuando filtro por A.id
en lugar de A.value
.
El gráfico de interbloqueo me dice que ambos desean establecer un bloqueo S en el índice de clave principal de la tabla A
. De nuevo: no hay escalada de bloqueo.
estoy usando SqlServer 2005.
- ¿Por qué son estas transacciones en conflicto sin tener acceso a los datos comunes? ¿Alguien puede explicar esto?
- ¿Qué puedo hacer para evitarlo? Estoy usando NHibernate y no puedo cambiar la consulta tan fácilmente.
- ¿Podría ser un problema SqlServer?
Muchas gracias.
¿Qué significa "/ * sincronizar las transacciones aquí * /"? –
@Mitch: Significa que ejecuto la transacción 1 hasta este punto, luego ejecuto la transacción 2, que espera en la selección, luego ejecuto la transacción 1 hasta el final, que también espera en la selección. –