Re: [firebase-br] "Semáforo" no Firebird

omar l m rosa omar em conesul.inf.br
Sex Jul 20 02:01:02 -03 2007


porque não usa um gerador para cada empresa?

numa trigger before insert, verifica qual a empresa para acessar o gerador 
correto

tipo new.lancamento = gen_id('lanc' + cast(cod_empresa as varchar(10)), 1);

or some like that.

Bai
omar



----- Original Message ----- 
From: "Rodrigo A. de Freitas" <rodrigo em solucoeseinformatica.com.br>
To: "'FireBase'" <lista em firebase.com.br>
Sent: Thursday, July 19, 2007 4:49 PM
Subject: [firebase-br] "Semáforo" no Firebird


Olá pessoal! Estou quebrando a cabeça para resolver um problema, gostaria
que vocês me dessem uma ajuda... Eu tenho a seguinte situação:



Tenho um sistema de gestão que é integrado à contabilidade, e este sistema é
multi-empresa. Todos lançamentos para as tabelas contábeis são feitos via
stored procedures. Na contabilidade, cada lançamento contábil deve receber
um número único que é zerado para cada combinação de exercício / empresa e
que obviamente não seguem paralelamente. Assim:



                    Empresa 1      Empresa  2      Empresa 3

Lanctos:       1 / 2007            34 / 2007        5467 / 2007

                    2 / 2007           35 / 2007        5468 / 2007



* o exercício mudou *



                   1 / 2008            1 / 2008             1 / 2008

                   2 / 2008            2 / 2008             2 / 2008



Muito bem. Acontece que o sistema é alimentado por dezenas de funcionários,
e praticamente todos os módulos geram lançamentos contábeis. Como o
sequenciamento dos lançamentos é feito de forma tosca (SELECT
MAX(COD_LANCAMENTO) FROM TABELA WHERE EMPRESA = 123), ocasionalmente
acontece de duas procedures diferentes disparadas ao mesmo tempo gerarem
lançamentos contábeis com a mesma numeração para a mesma empresa.



Eu pensei em montar um tipo de semáforo; Se houvesse como comunicar o
Firebird com uma interface externa, eu faria um webservice que enfileirasse
as requisições e disponibilizasse os números; Como não existe, eu preciso
criar esse mecanismo dentro do firebird. Pensei em algo assim:



- Crio uma tabela de semáforo com três campos: "Código da empresa",
"exercício" e "número do lançamento".  Cada stored procedure que fosse gerar
um lançamento contábil iria acessar esta tabela, procurar o último
lançamento para o exercício e empresa desejada e acrescentar 1 no número,
gravando o novo número do lançamento nesta tabela.



DÚVIDAS:



1) Para que este mecanismo funcione correntamente, eu precisaria fazer um
lock explicito na tabela que fornecerá os números de lançamentos. Seria esse
o select ?:



SELECT COD_LANCAMENTO FROM SEMAFORO WITH LOCK

WHERE EXERCICIO = 2007 AND EMPRESA = 1



2) Como libero o 'lock' depois de utilizado ?



3) Como faço para a minha stored procedure não gerar um deadlock e sim
aguardar a liberação do registro (uma como um 'REPEAT UNTIL IS LOCKED') para
continuar ? Existe essa possibilidade ou eu tenho que tratar isso dentro da
minha aplicação ?





[]'s


Rodrigo A. de Freitas

Análise & Desenvolvimento


Soluções & Informática









______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para editar sua configuração na lista, use o endereço 
http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
Para consultar mensagens antigas: http://firebase.com.br/pesquisa





Mais detalhes sobre a lista de discussão lista