Busquei maiores informações sobre lock de registros, e encontrei uma solução mais adequada para o seguinte problema:
1) Tabela: pedido
Tabela: itemspedido
Tabela: estoque
Problemas:
1) Atualizar o estoque e impedir a atualização de outros usuários;2) Atualizar o campo de status do pedido para atualizado após atualização de
todos os items do pedido;
Solução:
try
database.starttransaction
query1.sql.text := 'update pedido set status = "C" where nropedido = ' + ednro.text;
query1.execsql // Neste momento o registro do pedido sera lockado
while not itemspedido.eof
begin
query1.sql.text := 'update estoque set qtde = qtde + ' + edqtde.text + ' where codpro = ' + edprod.text;
query1.execsql // Neste momento o registro do produto sera atualizado e lockado
end;
database.commit // apos o while significa que tudo foi OK, conclui todas as atualizaçoes e libera os locks
except
// caso aconteca algum problema nao atualizará os registros e liberara todos os locks
database.rollback
end;
Neste exemplo, coloquei a atualizacao do pedido no inicio do bloco, numa abordagem inicial poderia pensar em erro na logica, porem como esta sendo tratado tudo dentro de uma transacao ou necessito lockar o registro do pedido no inicio e para isso eu executei o UPDATE e caso dê algum problema na execucao do bloco este registro nao sera atualizado.É muito interessante também abordar que os controles de timeout e niveis de isolamento, para o banco de dados utilizado.
Outro aspecto para discussão seria : Por que nao utilizar as opcoes do dataset de edit, update, post ... em vez de utilizar o execsql de uma query.
Entao pensemos no seguinte bloco
try
database.starttransaction
estoque.edit
estoque.qtde := estoque.qtde + edqtde.text
estoque.update
database.commit
except
database.rollback
end
Parece lógico e certo, mas para um ambiente monousuario, pois num ambiente multiusuário o valor da qtde sofre mudancas constantes e no momento que este bloco estiver sendo executado o valor de qtde ja foi atualizado por outro usuario e a informacao que voce esta trabalho é velha . Isto certamente nao acontecera num bloco de transacao via comando update pois ele sempre trabalhara com a qtde atual e travara o registro, entao observemos o comando update.update estoque
set qtde = qtde + ediqtde.text
where codpro = edtpro.text
Observe que qtde corresponde ao valor atual do banco e nao uma variavel armazenada pelo sistema a qual fica desatualizada.Nesta solucao o meu estoque e pedido estarao INTEGROS e nao me darao sustos em valores de saldos incorretos
0 comentários :: 738 - Lock de Registro
Postar um comentário