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. 
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