Concorrência e Persistência

Olá pessoal,

Tive um problema aqui no design de nossa aplicação com relação aos requisitos de concorrência e persistência da aplicação.

A questão é: usamos DBCP como pool de conexões onde, cada método da persistência é tratado como uma operação única de “ir ao banco”, pegar uma conexão, usar, fechar e sair do método. Até ai tudo bem; o problema é que, em métodos onde existe a possibilidade de N Threads entrarem simultâneamente, ocorreram erros de conexões fechadas, ou seja, uma Thread anterior já fechou a conexão que a Thread atual ainda estava usando.

O DBCP é single-trhead, portanto não tem tratamento para ambiente concorrente.

Solução Possível: syncronized nos métodos que apresentam o problema.

O problema é que acho que isso é um problema de design de aplicação, e sincronizar os métodos é apenas um remédio. Outra possível solução é usar um pool para ambientes de alta concorrência, onde já testei o tomcat-pool que diz ser exatamente para ambientes desse tipo, mas apresentou um resultado muito pior que o DBCP.

Minhas perguntas:
Realmente é um problema de design de aplicação?
Minhas soluções propostas são válidas?

Gostaria da opinião de vocês, sempre são muito válidas. :slight_smile:

Abraços pessoal.

Olá,

Bom, se você estiver trabalhando com plataforma JEE, uma solução natural seria encapsular as regras de negócio em EJB Session Stateless e utilizar
conexões do Datasource que é gerenciado pelo App. Server, dessa forma você não teria mais problemas de concorrência pois o container EJB gerencia
isso de forma eficiente através do pooling de EJB Session Stateless, e consequentemente também não teria problemas com as conexões do Datasource.
No cenário de sua aplicação, se você sincronizar os métodos você resolve o problema de acesso concorrente, contudo a performance da sua aplicação
(com relação a tempo de resposta, por exemplo) poderia sofrer um forte impacto, além disso você vai ter implementar estratégias para multi-threading
para evitar deadlocks e outros problemas (o que seria feito automaticamente pelo container se você utilizar EJB Session Stateless), a meu ver o ponto
está no acesso concorrente nos métodos e não no pooling.

[ ]'s

Olá :),

Pois bem, não usamos JEE, é uma aplicação Stand Alone que não roda em um containner.

Existe outro problema que acho que não lembrei de citar: Singletons…

As persistências são todas singleton, ai já viu a desgraça.

O que você falou sobre os sincronizar os métodos é verdade, perderemos desempenho, porém, como eu disse, é um remédio, e não resolve o problema, apenas os incidentes. A solução que encontrei, para ser implantada depois é de tirar os singletons e gerenciar de forma descente o instanciamento das classes de persistência (não usamos nenhum gerenciador de injeção de dependência por causa do desepenho), assim resolveremos o problema.

Mas agora com isso que você falou, eu vou dar uma olhada no source pra saber como é feito isso pelo JEE, certamente terei boas idéias lá :).

Vlw