Bloquear Tabela - Delphi - Fórum iMasters
Bloquear Tabela
Por RGarbeloto, Julho 7, 2009 em Delphi
RGarbeloto 0
Tenho um sistema desenvolvido em Delphi 7 com banco SQL Server 2005 Express conectado através de ADOTables. Uso uma tabela chamada SEQUENCIA, que armazena o número do documento da última venda. Quando mando salvar uma venda nova o sistema pega o número da última venda na tabela SEQUENCIA, acrescenta 1 e salva o número da nova venda na tabela SEQUENCIA para depois salvar a venda.
O problema é que quando é usado mais de um terminal, ao tentar gravar na tabela SEQUENCIA é apresentada a seguinte mensagem:
"A linha não pode ser localizada para atualização. Alguns valores podem ter sido alterados desde que foram lidos pela última vez"
Exatamente em que momento você quer bloquear a tabela? O Sql server tem comandos próprios para bloqueio de tabelas e linhas de registros (TABLELOCK e ROWLOCK se não me engano) para que você possa fazer updates e bloquear os registros até que o BD libere o acesso. Já tentou utilizá-los?
Eu queria bloquear a tabela através do componente ADO. Estes comandos que você citou devem ser do próprio SQL, não é? Eu estou começando a trabalhar com o ADO e o SQL Server e não conheço todos os recursos, ainda. Vi um outro artigo que fala sobre as propriedades CursorLocation e CursorType do componente ADOTable. Não sei se tem alguma coisa a ver com o que estou tentando fazer...
Interesses:RPG, Esportes, Musculação, Delphi, PHP, MySQL, C#, Java.
O que tá acontecendo é que você está tendo um problema de concorrência nos registros da tabela. A melhor solução é o que o Chronos sugeriu. Tu vai ter que dar um lock na tabela enquanto estiver usando ela para não ter erro de alguém chegar neste meio tempo, abrir o registro e atualizar.
Apropósito, só por curiosidade, este erro dá sempre? Acho que se tu usasse ela apenas no evento BeforePost da tabela tu não teria este erro com frequência. A não ser que ocorressem MUITOS, mas MUITOS cadastros simultâneos nesta tabela...
Bem, este erro dá sempre, sim. Como esta tabela é acessada por vários usuários ao mesmo tempo e o tempo todo, o que acontece é exatamete isso, a concorrência pelo acesso à tabela é muito grande.
Encontrei alguns artigos na internet sobre como configurar os componentes ADOTable e fiz algumas alterações:
Coloquei a propriedade CursorLocation em clUseServer, a propriedade CursorType em ctStatic e a propriedade LockType em itPessimistic.
Instalei o programa no cliente para fazer alguns testes e deu certo.
Vou aguardar mais uns dois dias pra ter certeza de que não vai dar mais nenhum problema e coloco o resultado aqui.
Por enquanto, agradeço demais a atenção e a ajuda de vocês.
É, pessoal, o problema continua! Em uma fraqüência menor, mas continua. Tentei vários tipos de combinação dos componentes ADO. Talvez o problema esteja por aí. Meus componentes estão configurados da seguinte forma:
ADOConnection: CursorLocation = clUseClient
IsolationLevel   = ilReadCommitted
Mode			   = cmReadWrite
ADOTable........: CursosLocation = clUseServer
CursorType	 = ctStatic
LockType		 = ltPessimistic
O código, no momento do acesso à tabela é o seguinte:
TbSequencia.Open;
TbSequencia.Edit;
TbSequenciaVendas.Value := TbSequenciaVendas.Value+1;
TbSequencia.Post;
EDNDoc.Text := FormatFloat('000000',TbSequenciaVendas.Value);
TbSequencia.Close;
Algo que eu acreditava ser tão rápido que não precisaria de travamento, pois eu fazia isso com Paradox sem problema algum...
Vi alguma coisa a respeito de Triggers, Stored Procedure, Relacionamentos, não sei se seria o caso, também, pois não entendo quase nada e tive que pular de cabeça no SQLServer porque o Paradox estava dando muitos problemas à medida que o sistema foi crescendo.