none
EVITAR BLOQUEOS DE TABLAS DE UN BASE DE DATOS RRS feed

  • Pregunta

  • Estimados amigos necesito saber como evitar que varias TABLAS se bloqueen, estoy realizando  una tarea programada que empieza a correr a las 2 de la mañana, el cual realiza una serie de procesos (cálculos) y cabe mencionar que tengo 1 millón de registros el cual toma su tiempo (y se bloquean las tablas), pero en todo este proceso mi SERVICIO sigue activo en la que los usuarios siguen  realizando operaciones como insert, update, delete , mencionar que todo este proceso se encuentra dentro de una transacción , la idea es que  durante todo este PROCESO EXISta tiempo para que las otras transacciones ingresen a realizar operaciones y que no esperen en cola hasta que finalice todo el PROCESO mencionado, una forma que invetigue fue colocar dentro de mi transacción un WAITFOR DELAY '00: 00: 00.010' para en ese pequeño lapso ingresen las otras transacciones

    que me recomiendan utilizar para tal objetivo.

    gracias

    martes, 16 de enero de 2018 21:48

Respuestas

  • Primera opción: Disminuir el nivel de aislamiento de la transacción. Puedes ejecutar al principio un comando de este tipo:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

    Esto elimina prácticamente todos los bloqueos. Pero: al no tener bloqueos, se leen los datos que están "a medio procesar", incluso pueden leerse datos de los que luego se hace un rollback. Esto hace que pierdas integridad de datos. Si tus transacciones son críticas y esto no es aceptable, hay que buscar otra opción.

    Segunda: Usar aislamiento por instantáneas en la transacción. Puedes usar la opción READ_COMMITTED_SNAPSHOT poniéndola en ON (o aislamiento de tipo SNAPSHOT) y esto hace que se use versionado de filas, con lo que las lecturas se hacen sobre una copia de la fila sin que se bloquee la fila sobre la que opera la transacción.

    https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql

    Tercera: si la tarea programada es de solo lectura (solo hace cálculos pero no modifica las tablas que no quieres bloquear), haz un snapshot de la base de datos (si tienes una edición de SQL Server que lo soporte) y lanza el proceso sobre el snapshot en lugar de sobre la base de datos real. Esto mismo también podrías hacerlo sobre una réplica o a un duplicado realizado por log shipping en modo standby, o un mirror en solo-lectura.

    martes, 16 de enero de 2018 22:19
  • Excelente respuesta Alberto, solo una aporte de mi lado, ya que tuve una discusión reciente sobre NOLOCK o Read Uncommited y el hecho que en realidad si aplica un único tipo de bloqueo, que por cierto es extremadamente remoto que se junten las circunstancias del mismo, en este caso en la fase de compilación requiere un Schema Stability Lock, aqui en link:  

    https://www.sqlpassion.at/archive/2014/01/21/myths-and-misconceptions-about-transaction-isolation-levels/?awt_l=LspIT&awt_m=3f5i3XSGzIYUUTS

    Saludos.


    "Oh, the wind, the wind is blowing,through the graves the wind is blowing,Freedom soon will come; then well come from the shadows".The Partisan(Leonard Cohen) Email: me[at]geohernandez.net Blog:www.geohernandez.net

    martes, 16 de enero de 2018 22:40

Todas las respuestas

  • Primera opción: Disminuir el nivel de aislamiento de la transacción. Puedes ejecutar al principio un comando de este tipo:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

    Esto elimina prácticamente todos los bloqueos. Pero: al no tener bloqueos, se leen los datos que están "a medio procesar", incluso pueden leerse datos de los que luego se hace un rollback. Esto hace que pierdas integridad de datos. Si tus transacciones son críticas y esto no es aceptable, hay que buscar otra opción.

    Segunda: Usar aislamiento por instantáneas en la transacción. Puedes usar la opción READ_COMMITTED_SNAPSHOT poniéndola en ON (o aislamiento de tipo SNAPSHOT) y esto hace que se use versionado de filas, con lo que las lecturas se hacen sobre una copia de la fila sin que se bloquee la fila sobre la que opera la transacción.

    https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql

    Tercera: si la tarea programada es de solo lectura (solo hace cálculos pero no modifica las tablas que no quieres bloquear), haz un snapshot de la base de datos (si tienes una edición de SQL Server que lo soporte) y lanza el proceso sobre el snapshot en lugar de sobre la base de datos real. Esto mismo también podrías hacerlo sobre una réplica o a un duplicado realizado por log shipping en modo standby, o un mirror en solo-lectura.

    martes, 16 de enero de 2018 22:19
  • Excelente respuesta Alberto, solo una aporte de mi lado, ya que tuve una discusión reciente sobre NOLOCK o Read Uncommited y el hecho que en realidad si aplica un único tipo de bloqueo, que por cierto es extremadamente remoto que se junten las circunstancias del mismo, en este caso en la fase de compilación requiere un Schema Stability Lock, aqui en link:  

    https://www.sqlpassion.at/archive/2014/01/21/myths-and-misconceptions-about-transaction-isolation-levels/?awt_l=LspIT&awt_m=3f5i3XSGzIYUUTS

    Saludos.


    "Oh, the wind, the wind is blowing,through the graves the wind is blowing,Freedom soon will come; then well come from the shadows".The Partisan(Leonard Cohen) Email: me[at]geohernandez.net Blog:www.geohernandez.net

    martes, 16 de enero de 2018 22:40