EJB e Problemas com concorrencia... (se eh que se pode chamar de concorrencia)

28 respostas
chun

Seguinte rapaziada… tenho o seguinte problema:

Tenho uma App JEE 5 rodando com session beans stateless e com cliente Swing…

Quando o usuario editar um “registro de uma determinada tabela” eu quero impedir que outro usuario edite o mesmo registro ( por ex: de uma outra estacao) , quero dar uma msg do tipo “Este registro já esta sendo editado em outra estacao”

A questao eh:

Existe alguma forma “menos porca” que colocar uma variavel estatica guardando os “id’s em uso” do lado do session bean ?

Valeu !!!

28 Respostas

Mauricio_Linhares

Você não deveria fazer dessa forma, deveria utilizar o suporte a versionamento do entity manager com travas otimistas.

Se você está utilizando o Hibernate -> http://www.hibernate.org/hib_docs/entitymanager/reference/en/html/transactions.html

chun

Sim , eu sei que o EntityManager é capaz de fazer versioning para evitar atualizações errôneas… porem eu gostaria de dar a MSG logo que o cara “clikar no botao alterar” e nao ao “salvar” entende ?

G

acho q uma solução seria controlar variavel do banco lock…

tipo alguma coisa como trancar o registro enquanto a 1º pessoa edita…
so que a 2º ficaria esperando até ficar unlock…

não sei se ajudei ? :thumbup: :thumbdown:

Mauricio_Linhares

chun:
Sim , eu sei que o EntityManager é capaz de fazer versioning para evitar atualizações errôneas… porem eu gostaria de dar a MSG logo que o cara “clikar no botao alterar” e nao ao “salvar” entende ?

Não entendi, você quer que quando o cara estiver inserindo um registro, se ele for inserido por outra pessoa, já apareça uma mensagem avisando que o registro já foi inserido?

Mas se o cara nem inseriu ainda, como é que outra pessoa pode alterar?

Você tá complicando uma coisa terrívelmente simples, pense bem se é isso mesmo que você quer fazer.

chun

Maurício Linhares:
chun:
Sim , eu sei que o EntityManager é capaz de fazer versioning para evitar atualizações errôneas… porem eu gostaria de dar a MSG logo que o cara “clikar no botao alterar” e nao ao “salvar” entende ?

Não entendi, você quer que quando o cara estiver inserindo um registro, se ele for inserido por outra pessoa, já apareça uma mensagem avisando que o registro já foi inserido?

Mas se o cara nem inseriu ainda, como é que outra pessoa pode alterar?

Você tá complicando uma coisa terrívelmente simples, pense bem se é isso mesmo que você quer fazer.

O que eu quero eh apenas ALTERACAO… esqueca a inclusao… o registro já vai tar lá… ae UM usuario vai apertar no botao ALTERAR e comecar editar (isso pode levar varios minutos, pois o cara no MEIO DE UMA ALTERACAO pode ir tomar um café…) … se por acaso OUTRO usuario de OUTRA maquina tentar editar o MESMO registro , quero que dê uma mensagem pra ele “Este registro já está sendo editado em outra estacao”

Mauricio_Linhares

Você já pensou na possibilidade do cara ir tomar o café, se engasgar e ir parar no hospital e aquele registro tiver que ser alterado pra fazer uma venda de alguns milhões de dólares?

Adivinha só quem é que vai perder o emprego :lol:

Mas é uma escolha sua, só tenha cuidado pra não se arrepender depois. Travas otimistas foram pensadas exatamente para este tipo de acontecimento.

chun

Você já pensou na possibilidade do cara ir tomar o café, se engasgar e ir parar no hospital e aquele registro tiver que ser alterado pra fazer uma venda de alguns milhões de dólares?

Adivinha só quem é que vai perder o emprego :lol:

Mas é uma escolha sua, só tenha cuidado pra não se arrepender depois. Travas otimistas foram pensadas exatamente para este tipo de acontecimento.

Resumindo… ou usa-se versionamento e tem-se um erro ao salvar o registro (caso ele tenha sido alterado por outra estacao) OU faz uma propriedade estadica no container , certio ?

Mauricio_Linhares

Não entendi esse negócio de propriedade estática.

louds

Se isso é tão importante p/ teu sistema, coloca uma tabela no banco indicando que está editando o que. Simples assim.

chun

louds:
Se isso é tão importante p/ teu sistema, coloca uma tabela no banco indicando que está editando o que. Simples assim.

Não seria mais elegante deixar um Sessionbean controlar isso? (usando um arraylist estatico nele e ponho lá os ID’s que estao em edicao) ae nao dependo do banco de dados…

Luca

Olá

Antes de 1997, enquanto usava Clipper, meus sistemas faziam mais ou menos isto. Só que precisei criar um sistemas de mensagens que aparecesse na tela de quem queria editar o registro em uso. É claro que precisa de um tempo máximo de edição para evitar o caso do cara que vai ao banheiro enquanto edita.

Para fazer isto hoje em dia, para mim o mais difícil é a parte da mensagem aparecer na tela do cliente. Acho que isto parece tarefa para Comet programming ou continuations do Jetty. Eu nunca usei estas coisas que prometem maravilhas. O Chun que é bom de Glassfish deve saber como fazer isto usando um artigo que está hoje no Java.net:

The Grizzly Comet or why space shuttle Discovery launch was delayed

[]s
Luca

chun

Luca:
Olá

Antes de 1997, enquanto usava Clipper, meus sistemas faziam mais ou menos isto. Só que precisei criar um sistemas de mensagens que aparecesse na tela de quem queria editar o registro em uso. É claro que precisa de um tempo máximo de edição para evitar o caso do cara que vai ao banheiro enquanto edita.

Para fazer isto hoje em dia, para mim o mais difícil é a parte da mensagem aparecer na tela do cliente. Acho que isto parece tarefa para Comet programming ou continuations do Jetty. Eu nunca usei estas coisas que prometem maravilhas. O Chun que é bom de Glassfish deve saber como fazer isto usando um artigo que está hoje no Java.net:

The Grizzly Comet or why space shuttle Discovery launch was delayed

[]s
Luca

Muito interessante… será que existe algo parecido que possa ser usado com EJB3+Swing ?

Luca

Olá

Em Swing deve ser bem mais fácil fazer pipocar uma mensagem na tela de quem tenta alterar um registro que está marcado como sendo editado. E para mim o meio mais fácil da saber isto é como o Louds disse.

[]s
Luca

plentz

louds, você provavelmente ainda não pegou um sistema com isso. E acredite, dói dar manutenção numa tralha dessas.

Travas otimistas++

Mauricio_Linhares

plentz:
louds, você provavelmente ainda não pegou um sistema com isso. E acredite, dói dar manutenção numa tralha dessas.

Travas otimistas++

Eu realmente estava achando que estava sozinho nisso :smiley:

WalterIM

Outra opção, na verdade a mais clássica de todas, do tipo que se usava no cobol:
Faça um código sql específico, dando lock de verdade quando a primeira edição acontecer e verificando se o registro está em lock quando a segunda leitura para posterior edição for tentada.

plentz

WalterIM:
Outra opção, na verdade a mais clássica de todas, do tipo que se usava no cobol:
Faça um código sql específico, dando lock de verdade quando a primeira edição acontecer e verificando se o registro está em lock quando a segunda leitura para posterior edição for tentada.

Algo não cheira bem nessa solução.

grprado

WalterIM:
Outra opção, na verdade a mais clássica de todas, do tipo que se usava no cobol:
Faça um código sql específico, dando lock de verdade quando a primeira edição acontecer e verificando se o registro está em lock quando a segunda leitura para posterior edição for tentada.

Eu estou fazendo assim também, mas porque me foi solicitado fazer assim.

Em um ambiente com alguma concorrencia vai dar pau. Ou você acha que usuários não saem para tomar cafézinho e largam o terminal idle no meio de um edit por 30 minutos?

Esse tipo de trava até tem aplicações,mas desde que: 1 - Não seja num ponto de muita concorrência e 2 - Os usuários saibam da implicação que um edit pode causar no sistema.

Além disso não esqueça de por no manual do software que o problema do cafézinho existe e pode acontecer, para que não venham depois pedindo sua cabeça.

Luca

Olá

Usei esta perfumaria durante muito tempo antes de 1997 quando usava Clipper sem nenhum problema. Só é preciso limitar o tempo que um registro pode permanecer aberto para edição.

Esta discussão se refere a caso de alterações em registros. Se o sistema permitir muitas alterações de registros talvez realmente possa haver algum inconveniente. Onde usei era um sistema de ERP com pouquíssimos lugares em que se podia editar registros. Pelo que me lembro os únicos locais em que se podia alterar registros eram nas tabelas de cadastro e de configuração. Nestas últimas o acesso era restrito aos administradores.

Na tabela de cadastro de clientes, cada vendedor cadastrava o cliente digitando nome diferente. O problema, ao invés de ser editar o mesmo registro, era impedir com busca tipo soundex, a inclusão de um novo quando já existia um antigo com nome digitado parecido.

[]s
Luca

WalterIM

grprado:
WalterIM:
Outra opção, na verdade a mais clássica de todas, do tipo que se usava no cobol:
Faça um código sql específico, dando lock de verdade quando a primeira edição acontecer e verificando se o registro está em lock quando a segunda leitura para posterior edição for tentada.

Eu estou fazendo assim também, mas porque me foi solicitado fazer assim.

Em um ambiente com alguma concorrencia vai dar pau. Ou você acha que usuários não saem para tomar cafézinho e largam o terminal idle no meio de um edit por 30 minutos?


Com certeza a melhor solução é a do lock otimista, mas dei essa sugestão porque o colega que começou a thread deu a entender que não poderia usar o lock otimista e teria que dar a mensagem antes do segundo usuário começar a editar.

grprado

Entendi seu ponto sim :slight_smile:

Cada caso tem que ser estudado e bem avaliado. O Pojos in Action tem um capítulo bem legal sobre quatro tipos de lock e quando usa-los.

louds

louds, você provavelmente ainda não pegou um sistema com isso. E acredite, dói dar manutenção numa tralha dessas.

Travas otimistas++

Concordo que optimistic locking é muito melhor nesse cenário. Mas se isso for um requisito do sistema, e fizer realmente sentido?

Sem utilizar uma tabela, uma boa forma de fazer isso seria usando memcached para guardar os locks e Comet style AJAX para garantir que não vamos ter locks mortos.

plentz

Opa, dai a coisa começa a ficar bem mais interessante. Mas acho que a primeira coisa a fazer é verificar qual tipo de lock é realmente necessário(se optimistic lock serviria nesse caso) ou se realmente, é requisito do sistema avisar o usuário já quando ele entrar no registro. Perder um tempinho avaliando isso pode te poupar dias de manutenção sofrida no futuro.

paulohbmetal

louds, você provavelmente ainda não pegou um sistema com isso. E acredite, dói dar manutenção numa tralha dessas.

Travas otimistas++

Pior que é… Imagina se a máquina do cara desliga ou cai a rede sei lá, no meio da edição do registro. O lock ficou no banco. E agora José?!

A Paz!!

Luca

Olá

paulohbmetal:
Pior que é… Imagina se a máquina do cara desliga ou cai a rede sei lá, no meio da edição do registro. O lock ficou no banco. E agora José?!

Antigamente este problema era resolvido facilmente logo na inicialização dos sistema verificando se havia locks travados. A gente guardava uma listinha em arquivo txt.

Na verdade todo este tópico é meio sem sentido. O que se quer fazer é pura perfumaria.

O modo mais normal de trabalhar com atualizações simultâneas é o modo otimista como muitos já escreveram:

  • Se abre o registro para edição de quantos estiverem a fim disto (que geralmente é raro ser mais de um)

  • O primeiro que tenta gravar consegue. Os demais são avisados de que o registro mudou e tchau. Em alguns casos recebem a tela com os novos valores no banco.

  • Em algumas aplicações se permite gravar também a alteração daquele que demorou mais tempo para salvar o registro com a possibilidade de fazer merge. Nunca vi isto mas sei que existe.

[]s
Luca

paulohbmetal

Luca:

Antigamente este problema era resolvido facilmente logo na inicialização dos sistema verificando se havia locks travados. A gente guardava uma listinha em arquivo txt.
[]s
Luca

No cliente?! :shock: Quando falei da energia cair é no cliente… Bom, só se locar com o id do usuário que locou e logo na reinicialização o mesmo voltar avisando que existem “tarefas” pendentes sei lá…

A Paz!!

Luca

Olá

Sim, no cliente com um arquivo TXT criptografado. E ainda com risco dele estar corrompido durante a queda do sistema. Mas já vi sistemas assim.

[]s
Luca

louds

louds, você provavelmente ainda não pegou um sistema com isso. E acredite, dói dar manutenção numa tralha dessas.

Travas otimistas++

Pior que é… Imagina se a máquina do cara desliga ou cai a rede sei lá, no meio da edição do registro. O lock ficou no banco. E agora José?!

A Paz!!

Ele quer esse recurso, então que se vire com os problemas técnicos para implementar.

Criado 7 de julho de 2006
Ultima resposta 20 de jul. de 2006
Respostas 28
Participantes 9