Controlar Transação de Informações Client DataSet
04/02/2010
Amigos, tenho um sistema de controle de estoque que irei utilizar em rede, utilizo para acesso ao banco os componentes: SqlDataSet, ClientDataSet e DataSetProvider, minha dúvida é o seguinte (ex): na minha tela de saída de itens a medida que estou adicionando os itens (produtos), ao adicionar, antes de dar um post na tabela itens, localizo o produto na tabela produto pego o campo estoque(campo da tabela Produto) e subtraio a quantidade de saída e em seguida efetuo um post nas tabelas produtos e itemsaída. Depois que termino de lançar os itens é que confirmo com o ApplyUpdates(0), para a tabela itens e a tabela produtos.
Daí vem um problema, e se outro usuário estiver editando a tabela produto ou até mesmo dando saída no estoque e efetuar um ApplyUpdates(0) na tabela produto antes que eu, daí se eu cancelar a saída vai dar “BO” no estoque né.. já que o applyUpdates na tabela produto foi efetuado por outra pessoa.
QUAL A MELHOR FORMA DE SE TRABALHAR COM ESSA SITUAÇÃO.
Pensei em trabalhar com a tabela produto apenas na confirmação, ou seja dar baixa no estoque só depois de lançar os itens e confirmar através de um evento (botão), mas daí vem a questão, e se após eu ter confirmado (ApplyUpdates(0)), eu querer editar um item ? que devo fazer.
Obrigado..
Posts
05/02/2010
Emerson Nascimento
se você trabalha com SGBDR, faça a movimentação de estoque através triggers - e stored procedures, se necessário.
caro EMERSON, uso sim SGBDR estou utilizando o firebird, é uma boa sim essa sua idéia, (triggers - e stored procedures), só me responde uma coisa... em que momento eu devo chamar esse procedimento, quando estiver adicionando o item? obrigado.
ps. se possível fico grato por uma orientação sua.
Neto
05/02/2010
Emerson Nascimento
use triggers (gatilhos) que deverão ser disparadas quando você grava um item (seja por inclusão ou por alteração).
não sei em que ramo de negócio você atua, mas não é normal haver alteração numa saída de produto.
geralmente cancela-se o item e cria-se um novo; no caso de pedidos de venda que depois geram notas fiscais, o processo de movimentação do estoque ocorre no momento da geração da nota fiscal.
de qualquer forma, no caso de alteração, basta você fazer uma continha para que o resultado dê certo:
- obtenha a quantidade do item ANTES da alteração.
- ao gravar, calcule a diferença entre a quantidade anterior e a nova quantidade
qtdmov = qtdatual - qtdanterior
- e, finalmente, faça a retirada do estoque
estoque = estoque - qtdmov
lembrando que triggers são disparados automaticamente. você deve definir o momento do disparo (ao incluir, ao alterar, ao excluir) quando criar o trigger.
Grande Emerson valeu pelas diacas, o sistema é um controle de estoque interno sem rotinas para vendas etc, apenas possui funções para saída, entrada e retorno (o material saíu do estoque mas pode retornar), utilizavamos ele em apenas um micro que ficava no almoxarifado (funcionava que uma maravilha), agora preciso utiliza-lo em rede, e programei daquela forma que falei no primeiro tópico, daí observei que daria pau no estoque. Ja trabelhei com procedimentos direto no banco, mas em rotinas simples como em um cadastro normal, sem depender de relacionamentos (master detalhe..). eu até entendi a suas dicas, mas me responde uma coisa, Se todas as vezes que estou lançando um item a trigger vai se encarregar de dar baixa no estoque e atualizar sem a necessidade de forçar um ApplyUpdates(0) isso num deixa o sistema mais lento, ou não? ja que todos os itens q forem lançados ja vão ser atualizados no momento do lançamento?
ah!!! e no caso da alteração a "continha" tem que ser efetuada no banco tbm?
Obrigado novamente.
05/02/2010
Emerson Nascimento
o trigger será disparado após o ApplyUpdates.
a conta deverá ser feita no trigger, para que seja gravado o valor correto no saldo do produto.
Grande Emerson, fiz as modificações e estou testando o sistema na
mesma maquina, abrindo ele duas vezes o programa. E Cadastros duas movimentações simultâneas.
Com as mesmas informações de item, (o mesmo produto nos dois cadastro). Quando mando
gravar, somente um cadastro dar baixa no
estoque (o que foi chamado primeiro), o outro não dar baixa no estoque. Mas se
cadastro com itens diferente n tem problema funciona legal para os dois
cadastro.
Será que eu utilizando na rede esse problema não vai
existir?
Obrigado
Neto.
05/02/2010
Perivaldo Martins
Creio que vc deveria pesquisar sobre nivel de isolamento, já que pretende rodar seu sistema em rede.
Boa sorte e bons códigos.
Citação de Neto"Quando mando gravar, somente um cadastro dar baixa no estoque (o que foi chamado primeiro), o outro não dar baixa no estoque. Mas se cadastro com itens diferente n tem problema funciona legal para os dois cadastro.
Será que eu utilizando na rede esse problema não vai existir? "
Configuração do Provider Flags Não ??????
como é citação neste editor ??????
06/02/2010
Emerson Nascimento
se vc fez via trigger não tem como dar erro. a menos que o trigger esteja errado.
Ola Emersom tudo bem.
Talves eu não tenha entendido por não acompanhar o tópico do inicio ,
mas acredito que configurando de modo equivocado o provider Flags não se
executa um applayUpdates e portando não se executa a Triger . Se fosse problema
de codificação da triger ele não conseguiria ter resultado nenhum . E ele relata somente
qns se esta modificando , alteranso o mesmo registro . Nesta situação acredito que um erro
esta sendo propagado e arriscaria nas configurações do Provider
Peço para colocar o evento ReconcileError do clientDataSet , para obeservar a mensagem lançada
a partir desta teremos opiniões mais precissas acerca do problema . Mas arrisco no ProviderFlags
06/02/2010
Emerson Nascimento
tudo beleza, MARCO SALLES?
realmente, se houve algum equivoco na configuração dos providerflag's,
poderá ocasionar algum erro na gravação do registro. mas creio que não houve
qualquer alteração e, portanto, todos os campos serão usados na
montagem das queries. sendo assim, pode não haver erro na gravação,
pois ele não acusa erro na gravação do registro, e sim na alteração do
saldo na tabela produto (a gravação ocorre numa tabela de itens de
venda).
Sim , mas leia novamente o Relato dele
Citação
"Com as mesmas informações de item, (o mesmo produto nos dois cadastro). "
Isto é , ele esta simulando um ambiente de Rede , aonde se abre o mesmo Registro
Vai um e altera dar o applayUpdates a Triger entra em ação e Atualiza ( faz o que tem que fazer)
Porém para o segundo usário na hora do TDataSetProvider do resolving , teremos valores
difentes na montagem desta queries , exatamente pela razão citada por vc:
Citação de Emerson
"todos os campos serão usados na montagem das queries."
Provavelmente ele esta configurando os Provider Flas com [pfInUpdate,pfInWhere] e o
TDataSetProvider a propriedade UpdateMode em upWhereAll
Esta é a minha sugestão....
07/02/2010
Emerson Nascimento
não, MARCOS. ele não abre o mesmo registro.
ele está fazendo duas vendas, uma em cada instância do sistema, utilizando o mesmo produto, para simular o ambiente de rede.
isso me dá a entender que ele grava as duas vendas (tabela itens de venda), porém apenas uma delas movimenta o estoque (tabela produtos). se as duas vendas foram gravadas, não há problema de providerflags.
pelo menos foi isso que eu entendi.
07/02/2010
Emerson Nascimento
desculpe, MARCO, grafei seu nome errado.
Amigos.. obrigado a todos pela ajuda. Não sei se estar correto, mas como utilizo o clientDataSet, e ele quando "aberto" buscas os registros e deixa em memória, percebi que ele estava buscando o valor do estoque na memoria, e quando eu adicionama o mesmo item em dois lançamentos ao mesmo tempo, e como o estoque que estava em memória era igual para todos os lançamentos o sistema dava baixa igualmente para as duas movimentações, porém os cálculos eram o mesmo, ja que o estoque em memória eram os mesmos para as dois lançamentos.(tabela ficava desatualizada) Deu pra etender?. Percebendo isso utilize o RefreshRecord na tabela produto e funcionou, Deixe em aberto este chamado para discurção, SERÁ QUE ESTE MÉTODO DE REFRESHRECORD está correto..
Obrigado a Todos novamente.