none
Como Bloquear y Desbloquer Tablas en SqlServer? RRS feed

  • Pregunta

  • hola

    Nesecito bloquear   2 tablas (ClienteTrack y Cliente)al comenzar mi procedimiento almacenado que inserta  registros en estas y al finalizar la insercion en la segunda tabla  desbloquear las tablas con el fin de que no se pueda insertar registros hasta que termine la operacion ...

    Como puedo hacer esto ??Mi Procedimiento almacenado :

    USE [DB_A3F354_RESTSYNC] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[Sp_InsertarClienteAll] ( @Id UNIQUEIDENTIFIER , @Nombre VARCHAR(50), @Edad INT, @Telefono VARCHAR(50), @Mail Varchar(50), @Saldo FLOAT, @FechaCreacion DATETIME, @FechaCreacionUtc DATETIME, @FechaModificacion DATETIME, @FechaModificacionUtc DATETIME, @Proceso VARCHAR(50), @Usuario VARCHAR(50), @Estado VARCHAR(50), @Transaccion VARCHAR(50) ) AS BEGIN SET NOCOUNT ON;

    INSERT INTO ClienteTrack ( Id, Nombre , Edad , Telefono , Mail,Saldo , FechaCreacion ,FechaCreacionUtc , FechaModificacion , FechaModificacionUtc , Proceso ,Usuario, Estado,Transaccion ) VALUES ( @Id, @Nombre , @Edad , @Telefono , @Mail, @Saldo , @FechaCreacion ,@FechaCreacionUtc , @FechaModificacion , @FechaModificacionUtc , @Proceso ,@Usuario, UPPER(@Estado),UPPER(@Transaccion)) INSERT INTO Cliente ( Id, Nombre ,Edad , Telefono , Mail, Saldo , FechaCreacion , FechaCreacionUtc , FechaModificacion , FechaModificacionUtc , Proceso , Usuario,Estado ) VALUES ( @Id, @Nombre ,@Edad , @Telefono ,@Mail, @Saldo , @FechaCreacion , @FechaCreacionUtc , @FechaModificacion , @FechaModificacionUtc ,@Proceso , @Usuario,UPPER(@Estado)); END ;



    EFRAIN MEJIAS C VALENCIA - VENEZUELA



    domingo, 12 de agosto de 2018 14:32

Respuestas

  • Lo más sencillo es que eleves el nivel de aislamiento de las transacciones con un comando SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, y luego encierres tus operaciones entre BEGIN TRANSACTION y COMMIT. La propia transacción bloqueará las tablas hasta que se complete.

    Si por alguna razón no puedes hacer esto mediante una transacción, entonces la solución es mucho más complicada. Tendrías que usar un bloqueo "lógico", empleando una tabla auxiliar para indicar "estamos ocupados" y forzando a que todos los accesos a las tablas que quieres bloquear pasen primero por examinar ese flag de "estamos ocupados".

    domingo, 12 de agosto de 2018 18:05

Todas las respuestas

  • Lo más sencillo es que eleves el nivel de aislamiento de las transacciones con un comando SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, y luego encierres tus operaciones entre BEGIN TRANSACTION y COMMIT. La propia transacción bloqueará las tablas hasta que se complete.

    Si por alguna razón no puedes hacer esto mediante una transacción, entonces la solución es mucho más complicada. Tendrías que usar un bloqueo "lógico", empleando una tabla auxiliar para indicar "estamos ocupados" y forzando a que todos los accesos a las tablas que quieres bloquear pasen primero por examinar ese flag de "estamos ocupados".

    domingo, 12 de agosto de 2018 18:05
  • Hola ... Alberto Poblacion

    Creo que esto es lo que trataste de decirme ?

    USE [DB_A3F354_RESTSYNC]
    GO
    /****** Object:  StoredProcedure [dbo].[Sp_InsertarClienteAll]    Script Date: 12/08/2018 15:28:13 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE [dbo].[Sp_InsertarClienteAll] 
    (
     @Id UNIQUEIDENTIFIER ,
     @Nombre VARCHAR(50),
     @Edad INT, 
     @Telefono VARCHAR(50),
     @Mail Varchar(50), 
     @Saldo FLOAT, 
     @FechaCreacion DATETIME,
     @FechaCreacionUtc DATETIME, 
     @FechaModificacion DATETIME, 
     @FechaModificacionUtc DATETIME,
     @Proceso VARCHAR(50),
     @Usuario VARCHAR(50),
     @Estado VARCHAR(50),
     @Transaccion VARCHAR(50)
    )
    AS
    BEGIN
    
    SET NOCOUNT ON;
    
    SET  TRANSACTION ISOLATION LEVEL SERIALIZABLE
    
    BEGIN TRAN
    
     INSERT INTO ClienteTrack (
       Id, Nombre ,
       Edad , Telefono , 
       Mail,Saldo , 
       FechaCreacion ,FechaCreacionUtc , 
       FechaModificacion , FechaModificacionUtc ,
       Proceso ,Usuario,
       Estado,Transaccion ) 
     VALUES (
       @Id, @Nombre ,
       @Edad , @Telefono ,
       @Mail, @Saldo , 
       @FechaCreacion , @FechaCreacionUtc , 
       @FechaModificacion , @FechaModificacionUtc ,
       @Proceso , @Usuario,
       UPPER(@Estado), UPPER(@Transaccion))
    
           INSERT INTO Cliente (
       Id,
       Nombre ,Edad , 
       Telefono , Mail,
       Saldo , FechaCreacion ,
       FechaCreacionUtc , FechaModificacion , 
       FechaModificacionUtc ,Proceso ,
       Usuario,Estado ) 
     VALUES (
       @Id,
       @Nombre ,@Edad , 
       @Telefono ,@Mail, 
       @Saldo , @FechaCreacion ,
       @FechaCreacionUtc , @FechaModificacion , 
       @FechaModificacionUtc ,@Proceso ,
       @Usuario,UPPER(@Estado));
    
        COMMIT TRAN
    
    END ;


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    domingo, 12 de agosto de 2018 19:47
  • Sí, esa era la idea. Si quieres probarlo, métele antes del COMMIT un "waitfor delay ...", para que se quede ahí parado un rato, y mientras está parado en el waitfor intenta grabar algo desde otra ventana en las mismas tablas. Verás que el comando de grabación se queda "atascado" y no graba nada (debido al bloqueo de las tablas) hasta que termina el waitfor y alcanza el commit, y en ese momento en que ya has salido del procedimiento almacenado entonces se hace la grabación que estaba parada en la otra ventana.
    lunes, 13 de agosto de 2018 8:25