none
Lock de Registro RRS feed

  • Pergunta

  •  

    Caros,

     

    1) Tenho uma tela de pedidos onde um usuario pode alterar.

    2) Enquanto um usuario estiver alterando um pedido por motivos diversos outro usuario não pode alterar, existe até um botão onde o usuario manifesta a vontade de alterar um pedido

     

    Pergunta como o ADO.NET trabalha desconectado como eu faria o lock do registro? Detalhe eu preciso fazer este lock de qualquer jeito.

     

    Obrigado a todos pela atenção.

    sexta-feira, 20 de junho de 2008 18:25

Respostas

  •  Jeronimo Alberto da Costa wrote:

     

    No primeiro item, controlar de que forma? O Usuario1 alterou o nome do cliente de X para Y e o Usuario 2 Alterou o nome do cliente de X para João quais as minhas alternativas?

     

    Como disse, no artigo que indiquei explica como fazer...

     

     Jeronimo Alberto da Costa wrote:

     

     

    Eu não trabalho diariamente com .NET, trabalho com eDeveloper(MAGIC) e temos condições de aplicar transações em varios niveis como no .NET. E lock de registro estando em modificação ou neste modelo de desconectado que seria o metodo Antes de Atualizar. Quando utilizamos o lock de registro em modificação o banco trava a linha e se der GPF o banco destrava sabendo que o usuario nao está conectado ao banco. O que eu queria saber se existe isso no .NET ou só desconectado.

     

     

    Bem, você teria que fazer o lock no banco de dados. Teria que abrir uma transaction quando começasse a alterar o registro e só finalizá-la depois. Como disse anteriormente, acho muito arriscado fazer isso...


    Ricardo Oneda
    http://oneda.mvps.org/blog

    domingo, 29 de junho de 2008 17:22

Todas as Respostas

  • Olá Jeronimo,

     

    O ADO.NET trabalha desconectado e conectado também !

    No seu caso você deve trabalhar conectado para controlar alteração no seu pedido.

     

    Se a resposta for útil por favor não esqueça de marca.
    Abraço,

     

     

    segunda-feira, 23 de junho de 2008 11:33
  • Daniel,

     

    Obrigado pela resposta. Mas como faria pra trabalhar conectado e efetuar o lock do registro?

     

    Obrigado

     

    segunda-feira, 23 de junho de 2008 14:50
  • Jeronimo,

    mesmo você tendo dito que precisa fazer o lock de qualquer jeito, vou ser teimoso

    Não acho essa uma boa idéia. Sugiro que você trate a concorrência no momento da atualização dos dados no banco de dados. Veja:

    Tackle Data Concurrency Exceptions Using the DataSet Object - http://msdn.microsoft.com/msdnmag/issues/03/04/DataConcurrency/default.aspx

     


    Ricardo Oneda
    http://oneda.mvps.org/blog

    segunda-feira, 23 de junho de 2008 15:18
  • Olá Jeronimo,

     

    Você pode criar uma Store Procedure com transação aqui tem exemplos de transação :

     

    http://msdn.microsoft.com/en-us/library/ms188929.aspx

     

    Ou se você quizer fazer no código você pode fazer assim

     

    Code Snippet

    protected void Button1_Click(object sender, EventArgs e)

    {

        //Configura command

        using (SqlCommand command = new SqlCommand())

        {

            using (SqlConnection connection = new SqlConnection("String de conexão"))

            {

                SqlTransaction transaction = null;

                try

                {

                    //Abre a conexão

                    connection.Open();

     

                    //Incia transação

                    transaction = connection.BeginTransaction();

     

                    //Configura o seu command e executa

                    command.CommandText = "INSERT INTO Tabela sss";

                    command.Connection = connection;

                    command.ExecuteNonQuery();

     

                    //Comita a transação

                    transaction.Commit();

                }

                catch (Exception)

                {

                    //Se der erro

                    transaction.Rollback();

                }

            }

        }

    }

     

     

     

    Se a resposta for útil por favor não esqueça de marca.
    Abraço,
    segunda-feira, 23 de junho de 2008 15:20
  • Daniel,

     

    Usar store procedure e o codigo mesmo assim estaria desconectado.

    Se duas pessoas alterar o registro fica o ultimo certo? É isso que não quero.

     

    Obrigado.

    segunda-feira, 23 de junho de 2008 15:27
  • Ricardo,

     

    Vc disse que não acha uma boa idéia. O que aconteceria se duas pessoas alteram o mesmo registro, fica a ultima?

     

    Obrigado.

     

    segunda-feira, 23 de junho de 2008 15:28
  • Jeronimo,

    depende, mas não precisa ser desse jeito obrigatoriamente. No artigo que indiquei há explicações do que pode ser feito.

     


    Ricardo Oneda
    http://oneda.mvps.org/blog

    quarta-feira, 25 de junho de 2008 11:37
  • Ricardo,

     

    Obrigado pela atenção.

    Mas mesmo pelo artigo e por aplicações que tenho visto por ai, até o SAP Business One. Das duas ou fica a ultima atualização ou avisa que o registro foi alterado por outro usuario.

    Imagine estou alterando o pedido ou cliente e digitei vários campos, outro usuario foi lá e atualizou o endereço ou algum dado do pedido, pronto o outro usuario tem que realizar um refresh do registro e digitar novamente?

    Independente desta questão você sabe como prender um registro para atualização?

     

    Desculpe ser insistente nisto, eu sei que trabalhar desconectado tem as suas vantagens, mas tem suas desvantagens também.

     

    Obrigado.

     

    quarta-feira, 25 de junho de 2008 12:33
  • Jeronimo,

     Jeronimo Alberto da Costa wrote:

    Imagine estou alterando o pedido ou cliente e digitei vários campos, outro usuario foi lá e atualizou o endereço ou algum dado do pedido, pronto o outro usuario tem que realizar um refresh do registro e digitar novamente?



    mas não precisa "perder" os dados. Você pode controlar isso na sua aplicação. Se o usuário quiser substituir o que está no banco de dados, você utiliza os dados que estão em memória. Isso vai depender da regra de negócio do seu sistema.

     Jeronimo Alberto da Costa wrote:

    Independente desta questão você sabe como prender um registro para atualização?
    Desculpe ser insistente nisto, eu sei que trabalhar desconectado tem as suas vantagens, mas tem suas desvantagens também.



    Não se trata de trabalhar desconectado ou não. Fazer esse tipo de "trava" implica em alguns riscos, e isso aconteceria tanto no modo conectado quanto desconectado. Você poderia criar um campo na tabela e, cada vez que o usuário entrasse na tela para edição, você gravaria alguma informação nesse campo que indicasse que o registro estivesse bloqueado. Assim, se outro usuário tentasse editar esse registro, vc poderia verificar esse campo antes. Mas imagine que um usuário entrou na tela mas por um motivo qualquer saiu da frente do computador. Esse registro vai ficar bloqueado por quanto tempo? Como tratar isso? São as necessidades de negócio que irão determinar esse comportamento...

     


    Ricardo Oneda
    http://oneda.mvps.org/blog

    quarta-feira, 25 de junho de 2008 16:21
  •  

    Ricardo,

     

     

    No primeiro item, controlar de que forma? O Usuario1 alterou o nome do cliente de X para Y e o Usuario 2 Alterou o nome do cliente de X para João quais as minhas alternativas?

     

     

    No segundo item, eu não faria esse tipo de lógica sabendo que alguem pode até dar GPF no sistema. O que eu falo é de executar um SELECT FOR UPDATE vc ja viu isso?

    Eu não trabalho diariamente com .NET, trabalho com eDeveloper(MAGIC) e temos condições de aplicar transações em varios niveis como no .NET. E lock de registro estando em modificação ou neste modelo de desconectado que seria o metodo Antes de Atualizar. Quando utilizamos o lock de registro em modificação o banco trava a linha e se der GPF o banco destrava sabendo que o usuario nao está conectado ao banco. O que eu queria saber se existe isso no .NET ou só desconectado.

     

    Ricardo muito obrigado pela atenção e desculpa ai pela insistencia.

     

    quarta-feira, 25 de junho de 2008 17:27
  • Jeronimo, acho que na verdade o que precisa é de um bloqueio em tela.
    Exemplo: no mesmo pedido um usuário não poder alterar o registro tal ao mesmo tempo em que outro usuário altera o mesmo registro.

    Dá pra fazer isso de forma simples colocando mais um campo na sua tabela, sei lá, "BLOQ BIT NOT NULL" algo assim. Onde quando o usuário entrar na tela do registo 1234, o campo é BLOQ é preenchido com 1 e quando o usuário termina/cancela a alteração o registro volta para 0.
    Antes de entrar na tela de alteração de registro a tela deve verificar se o mesmo já está bloqueado e só deixar o cara prosseguir na tela se o registro estiver marcado como não bloqueado.

    Essa solução é usada aqui na empresa e funciona muito bem, temos até uma tabela com todos os bloqueios utilizados, mas desta forma fica muito complexo.

    Acho que a solução de criar um novo campo bloq é bem mais simples e funcional.


    Espero ter ajudado.

    []s
    quarta-feira, 25 de junho de 2008 22:14
  • Waldyr,

    Não entendi como usar este recurso, teria um exemplo simples?
    Eu gostaria de fazer um lock do registro mesmo, pois pode ser q este registro seja alterado via integração de sistemas.

    Obrigado.


    Jeronimo
    sexta-feira, 27 de junho de 2008 12:33
  • Cara isso não é bem um recurso e sim uma solução para o caso de um usuário não poder alterar o mesmo registro ao mesmo tempo em que outro está alterando.
    Mas no caso de ter uma "batch" fazendo atualização, vc vai precisar mesmo de fazer um lock.
    http://www.arquitecturadesoftware.org/blogs/hugoribeiro/archive/2006/10/15/sql-server-transactions-locking-3.aspx
    dá uma olhada nesse post que ele deve te ajudar.

    Saiba que existem outras maneiras de se "emular" um lock, estas maneiras são usadas para bancos antigos ou que não dispõem do recurso de lock dentro do engine.

    Seria tipo assim, suponha que vc tenha uma tabela PEDIDO com os campos ID, DATA, CODPROD, CODUSU por exemplo.
    Para fazer um update, usando esse "lock" de gambiarra Smile

    Code Snippet

    CREATE PROCEDURE sp_AtualizaData
        @ID INT,
        @DATANOVA SMALLDATETIME
    AS
    BEGIN
        DECLARE @CODPROD INT, @CODUSU INT, @DATA SMALLDATETIME
        SELECT @CODPROD=CODPROD, @CODUSU=CODUSU, @DATA=DATA FROM PEDIDO WHERE ID=@ID
        UPDATE PEDIDO SET DATA=@DATANOVA WHERE ID=@ID AND CODPROD=@CODPROD AND CODUSU=@CODUSU AND DATA=@DATA

        IF @@ROWCOUNT = 0
            EXEC sp_AtualizaData @ID, @DATANOVA
    END


    O que acontece ai é o seguinte, ao fazer o select guardando os dados em variaveis vc tá criando uma especie de "lembrança", na qual o update vai usar para assegurar que os dados ainda são aqueles mesmo, ou seja, ninguem conseguiu mudar.
    Num caso critico, ao entrar no select os dados são trazidos, só que quando entra no update um outro usuário já teria modificado os dados e o update falharia. Então o IF logo em seguida se encarrega de verificar se o update teve efeito, e se o update não foi efetuado chama novamente a proc.

    Essa pode não ser a melhor solução, mas deve resolver o problema, afinal de contas o importante é gerar valor para nosso cliente.

    Smile

    []s


    sábado, 28 de junho de 2008 02:14
  •  Jeronimo Alberto da Costa wrote:

     

    No primeiro item, controlar de que forma? O Usuario1 alterou o nome do cliente de X para Y e o Usuario 2 Alterou o nome do cliente de X para João quais as minhas alternativas?

     

    Como disse, no artigo que indiquei explica como fazer...

     

     Jeronimo Alberto da Costa wrote:

     

     

    Eu não trabalho diariamente com .NET, trabalho com eDeveloper(MAGIC) e temos condições de aplicar transações em varios niveis como no .NET. E lock de registro estando em modificação ou neste modelo de desconectado que seria o metodo Antes de Atualizar. Quando utilizamos o lock de registro em modificação o banco trava a linha e se der GPF o banco destrava sabendo que o usuario nao está conectado ao banco. O que eu queria saber se existe isso no .NET ou só desconectado.

     

     

    Bem, você teria que fazer o lock no banco de dados. Teria que abrir uma transaction quando começasse a alterar o registro e só finalizá-la depois. Como disse anteriormente, acho muito arriscado fazer isso...


    Ricardo Oneda
    http://oneda.mvps.org/blog

    domingo, 29 de junho de 2008 17:22