sql-server - saber - revisar tablas bloqueadas sql server
cuándo/qué bloqueos se mantienen/liberan en el nivel de aislamiento LEER COMPROMETIDO (4)
Está haciendo la pregunta incorrecta, le preocupan los detalles de la implementación . En lo que debería pensar y preocuparse es por la semántica del nivel de aislamiento. Kendra Little tiene un bonito poster explicándolos: ¡ Free Poster! Guía de niveles de aislamiento de SQL Server .
Tu pregunta debe ser reformulada como:
seleccione * de Artículos
P: ¿Qué artículos voy a ver?
A: Todos los artículos comprometidos
P: ¿Qué sucede si hay transacciones no confirmadas que han insertado / eliminado / actualizado artículos?
R: su SELECT se bloqueará hasta que todos los elementos no comprometidos se confirmen (o se restituyan).
P: ¿Qué sucede si se insertan / eliminan / actualizan nuevos elementos mientras ejecuto la consulta anterior?
A: Los resultados son indeterminados. Es posible que veas algunas de las modificaciones, que no veas otras y que sea posible bloquear hasta que algunas de ellas se confirmen.
READ COMMITTED no hace ninguna promesa una vez que finalice su declaración, independientemente de la duración de la transacción. Si vuelve a ejecutar la instrucción, volverá a tener exactamente la misma semántica que el estado anterior, y los elementos que ha visto antes pueden cambiar, desaparecer y aparecer uno nuevo. Obviamente, esto implica que se pueden hacer cambios a los Artículos después de su selección.
Los niveles de aislamiento más altos brindan garantías más fuertes: REPEATABLE READ garantiza que ningún elemento que haya seleccionado la primera vez se puede modificar o eliminar hasta que realice la confirmación. SERIALIZABLE agrega la garantía de que ningún elemento nuevo puede aparecer en su segunda selección antes de comprometerse.
Esto es lo que necesita comprender, no cómo funciona el mecanismo de implementación. Después de dominar estos conceptos, puede solicitar los detalles de la implementación. Todos se describen en Procesamiento de transacciones: conceptos y técnicas .
Estoy tratando de entender el aislamiento / bloqueos en SQL Server.
Tengo el siguiente escenario en el nivel de aislamiento LEER COMPROMETIDO (predeterminado)
Tenemos una mesa.
create table Transactions(Tid int,amt int)
with some records
insert into Transactions values(1, 100)
insert into Transactions values(2, -50)
insert into Transactions values(3, 100)
insert into Transactions values(4, -100)
insert into Transactions values(5, 200)
Ahora desde msdn lo entendí
Cuando se realiza una selección, se toma un bloqueo compartido para que ninguna otra transacción pueda modificar los datos (evitando la mala lectura). La documentación también se refiere al nivel de fila, nivel de página y bloqueo de nivel de tabla. Pensé en seguir scenarion
Begin Transaction
select * from Transactions
/*
some buisness logic which takes 5 minutes
*/
Commit
Lo que quiero entender es por cuánto tiempo se adquirirá el bloqueo compartido y cuál (fila, página, tabla).
El bloqueo se adquirirá solo cuando se ejecute la instrucción select * from Transactions
o se adquirirá durante más de 5 minutos hasta que lleguemos a COMMIT.
Primero, el bloqueo solo se adquiere cuando se ejecuta la sentencia. Su declaración separa en dos partes, se supone que es simple:
select * from Transactions
update Transactions set amt = xxx where Tid = xxx
¿Cuándo / qué bloqueos se mantienen / liberan en el nivel de aislamiento LEER COMPROMETIDO? cuando se select * from Transactions
, no se obtiene bloqueo.
Las siguientes update Transactions set amt = xxx where Tid = xxx
agregará el bloqueo X para actualizar / actualizar las claves, IX bloqueo para la página / pestaña
Todo el bloqueo se liberará solo después de confirmado / revertido. Eso significa que ningún bloqueo se liberará en la ejecución trans.
Tu pregunta es buena. Comprender qué tipo de bloqueos se adquieren permite una comprensión profunda de los DBMS. En SQL Server, en todos los niveles de aislamiento (Lectura no confirmada, Lectura confirmada (predeterminada), Lecturas repetibles, Serializable) Se adquieren bloqueos exclusivos para las operaciones de escritura.
Los bloqueos exclusivos se liberan cuando finaliza la transacción, independientemente del nivel de aislamiento.
La diferencia entre los niveles de aislamiento se refiere a la forma en que se adquieren / liberan los bloqueos compartidos (leídos).
En el nivel de aislamiento Leer sin confirmar, no se adquieren bloqueos compartidos. Bajo este nivel de aislamiento, puede producirse el problema de concurrencia conocido como "Lecturas sucias" (una transacción puede leer datos de una fila que ha sido modificada por otra transacción en ejecución y que aún no se ha confirmado, por lo que podría revertirse).
En el nivel de aislamiento Lectura confirmada, los bloqueos compartidos se adquieren para los registros correspondientes. Los bloqueos compartidos se liberan cuando finaliza la instrucción actual. Este nivel de aislamiento evita las "lecturas sucias" pero, como el registro puede ser actualizado por otras transacciones concurrentes, las "lecturas no repetibles" (la transacción A recupera una fila, la transacción B actualiza la fila y la transacción A luego recupera la misma fila) La transacción A recupera la misma fila dos veces pero ve datos diferentes) o "Lecturas fantasma" (en el curso de una transacción, se ejecutan dos consultas idénticas y la recopilación de filas devueltas por la segunda consulta es diferente de la primera) .
En el nivel de aislamiento de lecturas repetidas, los bloqueos compartidos se adquieren durante la duración de la transacción. Las "lecturas sucias" y las "lecturas no repetibles" se evitan, pero las "lecturas fantasma" todavía pueden ocurrir.
Bajo el nivel de aislamiento Serializable, los bloqueos compartidos a distancia se adquieren para la duración de la transacción. No se produce ninguno de los problemas de concurrencia mencionados anteriormente, pero el rendimiento se reduce drásticamente y existe el riesgo de que se produzcan puntos muertos.
el bloqueo solo se adquirirá cuando se ejecute select * from Transaction
Puedes comprobarlo con el siguiente código
abrir una sesión de SQL y ejecutar esta consulta
Begin Transaction
select * from Transactions
WAITFOR DELAY ''00:05''
/*
some buisness logic which takes 5 minutes
*/
Commit
Abra otra sesión de SQL y ejecute debajo de la consulta
Begin Transaction
Update Transactions
Set = ...
where ....
commit