fantomas:
sfidencio:
Eu tenho estação rodando uma aplicação em Swing entende? essa estação vai ter um banco de dados possivelmente o derby ou mysql, essa estação prover um sistema de vendas com emissão de cupom fiscal e transferencia de fundos eletronicos(TEF).
1.após a efetivação da venda, o sistema irá chamar um serviço para enviar todos registros do sgbd local cujo flag de enviando ou nao na tabela é 'P' DE pendente, se for 'E' é porque ja enviou. a chave primaria será o código da operação fornecido pela impressora, e ele de forma alguma se repete entende? , portanto a minha duvida e como chamar o webservice exposto pelos pela minhas classes de serviços com Spring, de tal forma que eu populo o sgbd do servidor com segurança, ou seja, se a conexao for abortada, então eu nao comito local e nem remoto só isso meu amigo.
Humm...acho que agora entendi.
1) Para expor os serviços através do spring vc faz assim: [url]http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html[/url]
Perceba que quem vai expor os serviços é o spring através da configuração xml; ele irá criar um proxy baseado no objeto resultante da implementação do serviço (isto é transparente para nós). Significa que o serviço poderá ser utilizado pelo controller do módulo web e TAMBEM pelo client remoto sem problemas.
2) Em relação as transações a idéia que me veio foi de disponibilizar um serviço para informar se dado grupo de registros foram atualizados ou não com base na chave que os identifica. Aí ficaria assim:
a) Obter o registro com flag de enviado igual a P.
b) Executar o serviço remoto e verificar (através da chave) se o registro já foi atualizado.
c) Se o registro não foi atualizado então atualizar senão ignorar.
d) Se a atualização foi bem sucedida alterar o flag para E
As transações dos dois lados não são dependentes uma da outra. Significa que, poderá haver um commit em uma extremidade da comunicação e ocorrer um problema na rede antes da resposta chegar no client provocando um rollback.
Minha dúvida: A sua dúvida reside mais no ponto 1 ou no ponto 2?
flws
Fatomas, as transações estarão em contextos diferente como você disse, e pode haver que no servidor seja comitado e no cliente não em virtude do meio de comunicação ser interrompido, evidentemente, um roolback será chamado. Portanto, a minha dúvida está nos dois pontos, se ambos falhar? que tipo de algoritimo eu poderia fazer em ambos lados para verificar se existi algo Pendente em ambos os lados.? Imagina só: o Caixa 1 Vendeu 10.000,00 no dia, onde:
4000,00 Dinheiro
5000,00 Cartão de credito
1000,00 Cheque a prazo e a vista
Quando o usuario do sistema WEB for fazer o fechamento de caixa diario, para apurar a venda do caixa 1 irá perceber que está faltando 500,00 Reais, ou seja, existe um divergência de 500,00. Porque isso? Porque no Sistema de Caixa armazenamos dois tipos de movimento:
Movimento de Caixa (Leitura Z) - Esse movimento fica gravado na memoria Eprom da impressora fiscal (ECF)
Movimento de Produtos - Esse movimento fica gravado no banco de dados local
Esse dois tem que ser igual, imagina a falta dos 500,00 reais que teve. teremos uma diferença de 500,00. Isso não é outra coisa fatomas, o registro
que não foi sincronizado com a matriz.
Com base nisso, suponha que o commit do frente de caixa (swing app) não falhe, ou seja, ele alterou a FLAG, portanto não há possibilidade das rotinas automaticas (disparada via threads) tentar enviar tal registro novamente, visto que FLAG ja foi alterado, porém no servidor não foi alterada ainda. O que eu faço? Crio uma rotina no caixa para que o usuario forçe o enviou dos registros de determinada venda em um determinado periodo? Levando em conta que o registro não está no servidor e mesmo se tivesse ele ignoraria.
Veja só como ficaria a sequencia de implementação para enviou da venda do sistema PDV (swing) para o servidor (Web):
1. Seleciono as vendas pendentes na tabela Venda onde o status for igual a 'P', veja o schema da tabela venda:
Venda( coo(pk), data_mvto, status, enviado, usuario, Valor_Total)
Explicando:
coo = Codigo da operacao será a chave primaria
data_mvto = Data em que a venda foi realizada.
status = Se cumpom fiscal foi cancelado ou seja o cliente desistiu de comprar então gravo 'C' de cancelado ou 'N' de normal caso o cliente compre.
enviado = Se essa venda foi enviada ou não para o servidor a flag é 'P' de pendente, se foi enviada a FLAG é 'E' de enviado. (Ambos tem que confirmar o envio/recebimento)
Valor_Total = armazena o valor total da venda
Obs: Ao selecionar uma venda usando JPA/Hibernate posso trazer todos itens daquela venda caso o fech-join esteja habilitado, salvo erro, isso reduz pra mim quantidade de codigo se fosse fazer em SQL puro, logo eu tenho um objeto Venda que dentro dele como se trata de uma composição de objetos eu tenho varios obejtos que são os itens da Venda, resumindo eu farei a transferencia mais ou menos dessa forma me ajuda ai:
//Classe Implementação do Repositorio do Sistema de PDV Swing App.
public class VendaRepositoryJPAImpl implements VendaRepository {
List<Venda> vendasPendentes = em.createQuery(
"select cat from Cat as cat where cat.enviado:param1")
.setParameter(1)
.getResultList();
return vendasPendentes;
}
//Classe de serviço do Sistema PDV Swing App.
public void enviarVendaMatriz() {
//Crio o serviço
ServicoWeb servicoWeb = new ServicoWeb();
ServicoPorta servicoPorta = servicoWeb.getPorta();
//Diz ao servidor se foi comitado no cliente.
Boolean comitadoMatriz = false;
//Resposta do Servidor Matriz.
String respostaEnvioFilialMatriz;
//Respostar Local para ser enviada para o servidor.
String respostaEnvioMatrizFilial
//Obtenho as vendas pendetes
List<Venda> vendasPendentes = vendaRepositoy.obterVendasPendentes();
//Mando o Objeto todo..(Esse objeto não é tao gordo não, vai depender se não possui muitas vendas pendentes, o ideal é sempre está sincronizando )
//So vai devolver 'true' se foi realmente comitado..
respostaEnvio = servicoPorta.enviarVenda(vendaPendentes,comitadoMatriz);
//respostaEnvio pode receber: SUCESSO. FALHA
//Comito local caso ocorreu tudo certo no servidor..
if(repostaEnvio=="SUCESSO") {
//Tento comitar Local.. ou seja alterar a FLAG de P para E
vendaRepository.confirmarEnvioVendaMatriz(vendasPendentes);
}
if(respostaEnvio=="FALHA")
System.out.println("Falhou");
if(respostaEnvio=="EXISTE") //Comito localmente..
vendaRepository.confirmarEnvioVendaMatriz(vendasPendentes);
Fatomas de qualquer forma vai ter uma lado que ficará teoricamente em risco, de nao ter enviado. no caso o cliente, porque o cliente nesse caso tem feedback do servidor, porem o servidor nao tem do cliente...
Não vejo problema quanto a isso caso o cliente nao consiga comitar porque olhar só posso fazer o seguinte, guardar em uma tabela em ambos os lados, informações de sicronização. ou seja, guardo o ultimo COO que foi enviado, e toda vez
que eu tentar enviar,..eu verifico antes,se o ultimo COO existe no servidor, porque o que importa mais pra mim é o servidor.. ou seja, se o cliente nao enviou..a proxima vez ele tenta enviar..e se ele tentar enviar algo que já existe eu so comito localmente
qc acha?