none
Registro bloqueado RRS feed

  • Pergunta

  • Boa Tarde

    Pessoal estou com uma pequena dúvida existe uma forma de via comando sql saber qual registro de uma tabela esta bloqueado por outro utilizador? Vi alguns exemplos de tabela mas existe algo a nível de registro?

    segunda-feira, 31 de março de 2014 20:24

Respostas

  • Eder,

    O Lock de registros normalmente tem uma ação rápida.

    Eu particularmente conheço apenas o Lock de registros com versionamento por níveis de isolamento, mas acredito que para isso você terá de modificar seu banco de dados utilizando à configuração SNAPSHOT ISOLATION.

    Veja o conteúdo abaixo:

    http://technet.microsoft.com/en-us/library/ms187101(v=sql.105).aspx

    http://technet.microsoft.com/en-us/library/ms175095(v=sql.105).aspx

    Se ajudou na sua solução, não esqueça de marcar como resposta !

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    quarta-feira, 2 de abril de 2014 18:21
    Moderador
  • Éder,

    Sinceramente eu também pouco tive a necessidade de trabalhar com este tipo de cenário, mas tenho um exemplo que peguei a algum tempo com um colega e talvez possa ajudar:

    CREATE TABLE [dbo].[Tabelas](
     [idTabela] [int] NOT NULL,
     [NomeTabela] [varchar](100) NOT NULL,
     CONSTRAINT [PK11] PRIMARY KEY NONCLUSTERED 
    (
     [idTabela] ASC
    ))
    
    Go
    
    Insert Into Tabelas Values (1, 'Acao')
    Insert Into Tabelas Values (2, 'AcaoSistema')
    Insert Into Tabelas Values (3, 'Acomodacao')
    Insert Into Tabelas Values (4, 'Ajuda')
    Insert Into Tabelas Values (5, 'Alergia')
    Insert Into Tabelas Values (6, 'Alimento')
    Insert Into Tabelas Values (7, 'AlimentoReferencia')
    Insert Into Tabelas Values (8, 'AMB')
    Insert Into Tabelas Values (9, 'Arquivo')
    Insert Into Tabelas Values (10, 'Associado')
    
    Vamos lá, para testar o que eu estou falando abra duas sessões do SQL, nós vamos executar um script em cada sessão ao mesmo tempo.
    
    Na primeira, vamos bloquear o registro por 15 segundos, daqui a 1 minutor (mas para dar tempo de sincronizar os dois scripts).
    
    Begin Transaction
    
     Declare @InicioScript DateTime
    
        set @InicioScript = DateAdd(minute, 1, getdate())
    
     Waitfor time @InicioScript
    
        Select getdate()
    
     SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
     
        Select Top(1) * from Tabelas With (nowait, updlock, readpast)
    
     WaitFor Delay '00:00:15'
    
    rollback Transaction
    
     
    
    Rapidamente execute esse script na segunda sessão, ele vai começar daqui a 1 minuto e 5 segundos (para dar tempo da primeira sessão bloquear o registro).
    
    Begin Transaction
     Declare @InicioScript DateTime
        set @InicioScript = DateAdd(second, 5, DateAdd(minute, 1, getdate()))
    
     Waitfor time @InicioScript
    
        Select getdate()
    
     SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    
     BEGIN TRY
      Update Tabelas with (nowait) set [NomeTabela] = 'ssss' Where [idTabela] = 1
     END TRY
     BEGIN CATCH
       Select 'Erro Lock: ' + Cast(@@ERROR as VarChar) 
        END CATCH;
    
    rollback Transaction
    

    Vale ressaltar que o bloco de código simula o uso do Nível de Isolamento Read Uncommitted, o que nos permite ter leitura suja de dados.

    A um tempo eu vi situação similar fazendo uso dos Hint tables: NoWait, ReadPast, UpdLock, justamente para forçar o bloqueio do registro.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    sexta-feira, 4 de abril de 2014 18:25

Todas as Respostas

  • Eder,

    O Lock de registros normalmente tem uma ação rápida.

    Eu particularmente conheço apenas o Lock de registros com versionamento por níveis de isolamento, mas acredito que para isso você terá de modificar seu banco de dados utilizando à configuração SNAPSHOT ISOLATION.

    Veja o conteúdo abaixo:

    http://technet.microsoft.com/en-us/library/ms187101(v=sql.105).aspx

    http://technet.microsoft.com/en-us/library/ms175095(v=sql.105).aspx

    Se ajudou na sua solução, não esqueça de marcar como resposta !

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    quarta-feira, 2 de abril de 2014 18:21
    Moderador
  • Deleted
    quarta-feira, 2 de abril de 2014 19:28
  • Éder,

    Sinceramente eu também pouco tive a necessidade de trabalhar com este tipo de cenário, mas tenho um exemplo que peguei a algum tempo com um colega e talvez possa ajudar:

    CREATE TABLE [dbo].[Tabelas](
     [idTabela] [int] NOT NULL,
     [NomeTabela] [varchar](100) NOT NULL,
     CONSTRAINT [PK11] PRIMARY KEY NONCLUSTERED 
    (
     [idTabela] ASC
    ))
    
    Go
    
    Insert Into Tabelas Values (1, 'Acao')
    Insert Into Tabelas Values (2, 'AcaoSistema')
    Insert Into Tabelas Values (3, 'Acomodacao')
    Insert Into Tabelas Values (4, 'Ajuda')
    Insert Into Tabelas Values (5, 'Alergia')
    Insert Into Tabelas Values (6, 'Alimento')
    Insert Into Tabelas Values (7, 'AlimentoReferencia')
    Insert Into Tabelas Values (8, 'AMB')
    Insert Into Tabelas Values (9, 'Arquivo')
    Insert Into Tabelas Values (10, 'Associado')
    
    Vamos lá, para testar o que eu estou falando abra duas sessões do SQL, nós vamos executar um script em cada sessão ao mesmo tempo.
    
    Na primeira, vamos bloquear o registro por 15 segundos, daqui a 1 minutor (mas para dar tempo de sincronizar os dois scripts).
    
    Begin Transaction
    
     Declare @InicioScript DateTime
    
        set @InicioScript = DateAdd(minute, 1, getdate())
    
     Waitfor time @InicioScript
    
        Select getdate()
    
     SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
     
        Select Top(1) * from Tabelas With (nowait, updlock, readpast)
    
     WaitFor Delay '00:00:15'
    
    rollback Transaction
    
     
    
    Rapidamente execute esse script na segunda sessão, ele vai começar daqui a 1 minuto e 5 segundos (para dar tempo da primeira sessão bloquear o registro).
    
    Begin Transaction
     Declare @InicioScript DateTime
        set @InicioScript = DateAdd(second, 5, DateAdd(minute, 1, getdate()))
    
     Waitfor time @InicioScript
    
        Select getdate()
    
     SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    
     BEGIN TRY
      Update Tabelas with (nowait) set [NomeTabela] = 'ssss' Where [idTabela] = 1
     END TRY
     BEGIN CATCH
       Select 'Erro Lock: ' + Cast(@@ERROR as VarChar) 
        END CATCH;
    
    rollback Transaction
    

    Vale ressaltar que o bloco de código simula o uso do Nível de Isolamento Read Uncommitted, o que nos permite ter leitura suja de dados.

    A um tempo eu vi situação similar fazendo uso dos Hint tables: NoWait, ReadPast, UpdLock, justamente para forçar o bloqueio do registro.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    sexta-feira, 4 de abril de 2014 18:25