Evitar duas maquinas salvarem ao mesmo tempo

Ola pessoal,

Estou com um problema que diz respeito mais a DB do que propriamente a Java apesar de nao ser uma coisa tao avançada.

Tenho um aplicativo que verifica varios arquivos em uma arvore e salva as informacoes sobre os mesmos de modo que ele so deve rodar uma vez por dia. Acontece que eu devo previnir que duas maquinas rodem o aplicativo ao mesmo tempo de modo que nao possa haver informacoes duplicadas pra um mesmo dia sobre os arquivos. Mas como só faço o commit depois de verificar todos os arquivos nesse meio tempo(o que nao é pouco, coisa de 10min) outra maquina poderia rodar e tentar salvar as informacoes. Tudo bem que o commit de um deles nao seria aceito por causa da restricao de chave mas eu queria que o segundo aplicativo sequer tentasse gravar e emitisse logo uma mensagem pra evitar de esperar 10 min e emitir um erro. Atualmente estou salvando um arquivo inicial com a data do dia, dando commit nele e verificando se essa tupla existe sempre que o aplicativo inicia. Mas eu pensei que poderia haver outra solucao que nao essa. Se alguem ja passou pelo mesmo problema e resolveu de outra forma gostaria de saber como.

Desde ja agradeço.

se eu entendi bem você citou 2 formas de fazer:

[quote=carlos.e.a]
Acontece que eu devo previnir que duas maquinas rodem o aplicativo ao mesmo tempo de modo que nao possa haver informacoes duplicadas pra um mesmo dia sobre os arquivos.
Desde ja agradeço.[/quote]

não seria usar um Singleton ?

eu colocaria um campo nesta tabela que grava as informações da árvore boolean ou bit dependendo do banco, quando o processo fosse iniciado eu gravaria true e antes de iniciar outro processo eu daria um select no campo e faria o método pricipal só executar caso retornasse false, que acha ?

passei por problema semelhante e fiz isto que falei, fiz uma pouco mais na verdade, peguei os (pid) das conexões e verifiquei os processos que eram originados daquela tabela, abertos a muito tempo e por alguma razão até desconhecida não terminassem e ficassem travados no banco, eu matava esses processos e setava o campo bit para false e com uma nova thread eu disparava o processo novamente de forma automatica, claro, nossos contextos diferem um pouco.

Ola aix, obrigrado pela resposta!

Desculpe a ignorancia mas eu nao sei o que é Singleton. Vou pesquisar =D

Nao entendi essa do campo. Voce quis dizer colocar uma coluna na tabela? Ou criar outra tabela com apenas um boolean? Pq se for incluir um campo acho que nao funcionaria ja que o commit dele tambem so seria colocado ao salvar tudo…

Bom, pelo jeito entao nao estou taaao no caminho errado ne? Tipo, achei que poderia haver uma solucao “default” pra esse tipo de problema. Nao é considerado “gambiarra” eu fazer o que estou fazendo entao ne?

edit: Acabei de dar uma olhada no singleton. Acho que o padrao nao iria funcionar ja que o aplicativo esta instalado localmente e no caso pelo que li o padrao somente garante que vou ter somente uma instancia da classe. Falando a muito grosso modo seria como se fosse um “static aplicado a classe”…

sim adicionar uma coluna na tabela e dar um update na mesma quando o processo é iniciado.

não sei até que ponto é prejudicial para sua aplicação, mas pelo que vi vc tem um problema que sua aplicação permite 2 processos simulteanos rodarem, e vc disse que só a verificação para ver isto são quase 10 minutos, se usar o esquema que te falei do campo adicionado na tabela, você dara um select nele, estando configurado com true significa que ja tem processo rodando, se roda só uma vez por dia, ótimo não ira rodar uma segunda, pois eu iria alterar o método do processo principal o que inicia tudo para só rodar caso o select retorne false.

é realmente o singleton não serve neste contexto.

Hum, entendi. Como falei atualmente estou fazendo bem parecido. Eu estou salvando uma tupla com dados genericos e com a data do dia. Ai faço a verificacao se ja tem dados para aquele dia logo no inicio de um novo processo. Ai depois de tudo salvo e commitado eu removo a linha que adicionei.

Nao é prejudicial em nada na verdade, eu so quis livrar minha consciencia de estar fazendo “gambiarra” e passei aqui pra saber como o pessoal que ja passou por isso resolveu o problema. Mas pelo que vejo nao ha uma solucao “default” e que essa solucao que estou usando é aceitavel!

Agradeço a resposta aix e caso alguem tenha algo mais a acrescentar seria bem vindo.

ahhhh agora sim, entendi… você tem razão, na verdade é praticamente a mesma decisão que tomei, também não vejo nada de ruim não sendo assim conforme você falou, e deconheço um tipo default de fazer isto.

Se for um app web, você pode controlar pelo escopo application. Quando iniciar o serviço, você joga um flag no application. Qualquer outro que tente rodar não conseguirá até não existir mais este flag

legal sua idéia em controlar pelo escopo da aplicação, no meu caso foi mais util resolver no banco pois eu precisava controlar as conexões que ficavam ativas e garantir que serviços não ficassem la trancados em casos de erros , era uma app que se baseava toda no SQLServer, quem trabalhava de verdade era o banco o java fazia pouca coisa.

aaah, show de bola então :wink:

No meu caso a app é desktop mesmo. Se fosse web acho que haveriam realmente outras solucoes.