Estratégia de gerenciamento de session

5 respostas
R

Pessoal, estou com um problema e não consigo resolvê-lo.
Tenho um sistema em JSF + Hibernate + Primefaces + PostgreSQL que trabalha com uns 20 usuários logados simultaneamente, não tive problema nenhum até agora, mas o sistema está crescendo e estou percebendo que as conexões estão crescendo desenfreadamente no PostgreSQL, implementei o c3p0, mas mesmo assim as conexões continuam aumentando.
Descobri que o problema estava em não fechar as sessions, EU NÃO ESTAVA FAZENDO ISTO, eu abria a session no contrutor do meu managebean, usava ela onde precisasse e a largava lá.
Blz, descobri o problema, vamos fechar todas as sessions que eu abri e resolvido, mas ai bati de frente com o LazyLoadingException e não sei como resolvê-lo, na verdade, não tem como resolver a não ser que passe todas as minhas listas para EAGER, eu não posso fazer isto, senão vai ficar uma carroça.
A estratégia de Open Session In View também não serve para mim, tenho várias listas que são abertas com ajax, por exemplo: Tenho a classe Cliente, nela tenho a List<Animais>, List<ContasAReceber> e List<Compras>, na minha tela de cliente eu tenho um tabView e cada aba é uma destas lista, eu só carrego a lista quando o usuário clica na aba referente no tabView.

Pensei em fazer o seguinte: Deixar uma session aberta para cada usuário, durante todo o acesso dele, só fecharia esta session quando ele se desconectasse.

O queê vocês acham que devo fazer?

5 Respostas

Hebert_Coelho

Quatro soluções para LazyInitializationException, aqui tem outras 3 soluções além do Open Session In View.

Não deixe conexões abertas para cada usuário durante a sessão deles, é uma péssima prática isso.

R

Hebert Coelho:
Quatro soluções para LazyInitializationException, aqui tem outras 3 soluções além do Open Session In View.

Não deixe conexões abertas para cada usuário durante a sessão deles, é uma péssima prática isso.

Hebert, eu li o seu post, muito bom por sinal, eu já li várias coisas no seu blog, parabéns.

Voltando ao assunto, fazer o join query resolveria, por que eu posso deixar meus objetos como lazy e no join fech carregá-los, como se fossem EAGER, mas isto fica complicado para a minha arquitetura.

Eu fiz um mecanismo de pesquisa que utiliza uma classe única, com pouquíssimo código, se for usar o join fech terei que escrever pra cada classe pesquisável um join fech diferente, daria muito trabalho, se não tiver outra maneira, vou ter que fazer.

Mas qual seria o problema se eu deixar uma session aberta para cada usuário?

Hebert_Coelho

Raiduster:
Hebert, eu li o seu post, muito bom por sinal, eu já li várias coisas no seu blog, parabéns.

Voltando ao assunto, fazer o join query resolveria, por que eu posso deixar meus objetos como lazy e no join fech carregá-los, como se fossem EAGER, mas isto fica complicado para a minha arquitetura.

Eu fiz um mecanismo de pesquisa que utiliza uma classe única, com pouquíssimo código, se for usar o join fech terei que escrever pra cada classe pesquisável um join fech diferente, daria muito trabalho, se não tiver outra maneira, vou ter que fazer.

Mas qual seria o problema se eu deixar uma session aberta para cada usuário?

Opa, valeu pelo apoio.

O problema de deixa conexão aberta é consumo de recurso do banco, e de rede. O correto é abriu transação, fez o que deveria fazer, fechou.
Imagine se o usuário abrir uma conexão em cada browser no pc dele. Se ele tiver 3 browsers e conectar na aplicação você vai ter 3 para um apenas, e se multiplicar x 20 (seus usuários) você terá 60 conexões abertas. Uma hipótese menos radical seria o usuário abrir apenas num navegador, mas várias abas. Ferrou o banco.

Várias conexões abertas direto podem piorar o desempenho do banco, ou até mesmo negar solicitações de novas conexões.

Nunca vi um sistema com esse tipo de abordagem.

mateusviccari

Eu nao gosto de usar essas listas na classe pai, prefiro carregar a lista manualmente através da chave estrangeira, por exemplo

session.createQuery("from ItensDaVenda where venda.codigoDaVenda="+codigoDaVenda).list();

Assim abro a sessão pra carregar a venda e fecho a sessão, quando o usuario clicar pra ver os itens abro a sessão, executo essa query e fecho a sessão.

Hebert_Coelho

mateusviccari:
Eu nao gosto de usar essas listas na classe pai, prefiro carregar a lista manualmente através da chave estrangeira, por exemplo

session.createQuery("from ItensDaVenda where venda.codigoDaVenda="+codigoDaVenda).list();

Assim abro a sessão pra carregar a venda e fecho a sessão, quando o usuario clicar pra ver os itens abro a sessão, executo essa query e fecho a sessão.

Só tome cuidado com o modo em que a query é feita pois você poderá sofrer SQL Injection ao realizar a consulta como acima.

Criado 17 de outubro de 2012
Ultima resposta 18 de out. de 2012
Respostas 5
Participantes 3