Tenho uma aplicacao que usa o Hibernate, no xml de configuracao configurei o c3p0 para trabalhar com o numero maximo de 60 conexoes, no banco a config esta para no maximo 100 conexões. Minha aplicação cria um pool de threads onde o tamanho deste pool é de 50, cada thread se conecta em um equipamento via telnet busca os dados e grava na base. O que eu acho interessante é que sempre tenho um valor entre 40 e 50 conexões telnet na minha maquina, porém quando listo as conexões abertas e estabelecidas na porta do postgresql esta com 126 conexões. Outro detalhe é que minha aplicação após um certo momento fica bem lenta onde a coleta dos dados é feita de forma bem insatisfatória, alguem sabe o que pode estar acontecendo?
Olá meu amigo o que está acotencendo é que ele não esta fechando as conexões com o banco de dados.
se o sistema for web vc pode dar uma olhada no pattern open session view
Pedrosa
Já pensou em deixar essa parte burocrática para o Spring gerenciar?
Além de gerenciar suas conexoes ele também lida melhor com transações.
pauloperes
Kra,
imaginei que poderia ser isto, entao no final de cada thread dei um close na session, porem aconteceu de eu receber o erro de que a minha conexao ja estava fechada, quando uma outra thread é executada
pauloperes
Sabe como eu faço isto com spring?
bruno_savi
dependendo do andamento que o projeto está, prazo custo e etc… não compensa tentar implantar um spring neste momento
utilize o filter do hibernate e depois pense numa solução melhor
Basicamente vc vai ter as mesmas configurações do hibernate.cfg.xml no arquivo de configuração do Spring inclusive suporte a c3po:
De uma olhada na documentação a parte de integração com Hibernate:
pauloperes
So para vcs entenderem melhor, segue minhas classes
Thread:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */packagebr.com.gvt.milegateinventory.core;importbr.com.dao.Dao;importbr.com.dao.DaoCard;importbr.com.exception.DaoException;importbr.com.gvt.loglib.core.Log;importbr.com.gvt.milegate.core.Core;importbr.com.gvt.milegate.exception.MilegateConnectionException;importbr.com.gvt.milegate.exception.MilegateException;importbr.com.gvt.milegate.function.BackupAdsl;importbr.com.gvt.milegate.function.PortAdslFunc;importbr.com.gvt.milegate.function.ProfileAdslFunction;importbr.com.gvt.milegate.function.ProfileChanFunction;importbr.com.gvt.milegate.function.ShelfFunc;importbr.com.gvt.milegate.function.UnitFunc;importbr.com.gvt.milegate.telnet.TelnetCore;importbr.com.hibernate.HibernateCore;importbr.com.model.Card;importbr.com.model.Port;importbr.com.model.ProfileMilegate;importbr.com.model.Shelf;importjava.io.File;importjava.io.IOException;importjava.util.ArrayList;importjava.util.Calendar;importjava.util.List;importjava.util.logging.Level;importjava.util.logging.Logger;importorg.jdom.JDOMException;/** * * @author paulo */publicclassThreadInventoryimplementsRunnable{privateShelfshelf;privateTelnetCoretelnetCore=newTelnetCore();privateCorecore=newCore(telnetCore);privateShelfFuncshelfFunc=newShelfFunc(telnetCore);privateUnitFuncunitFunc=newUnitFunc(telnetCore);privateList<Card>cards=null;privatePortAdslFuncportAdslFunc=newPortAdslFunc(telnetCore);privateDao<Port>daoPort;privateDao<Card>daoCard;privateDao<ProfileMilegate>daoProfile;privateStringftpserver;privateStringftpusername;privateStringftppassword;publicThreadInventory(Shelfshelf){this.shelf=shelf;}publicThreadInventory(Shelfshelf,Stringftpserver,Stringftpusername,Stringftppassword){this.shelf=shelf;this.ftpserver=ftpserver;this.ftpusername=ftpusername;this.ftppassword=ftppassword;}publicvoidpersistenceAdslPortsFromFileBackup(Stringfile){BackupAdslbackupAdsl=newBackupAdsl();List<Port>ports=newArrayList<Port>();for(Cardc:cards){try{ports.addAll(backupAdsl.getAdslConfigurationBySlot(c,file));}catch(JDOMExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar as configurações de porta ADSL: "+shelf.getIp()+"(unit-"+c.getSlot()+")\n"+ex.getMessage()+"\n");}catch(IOExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar as configurações de porta ADSL: "+shelf.getIp()+"(unit-"+c.getSlot()+")\n"+ex.getMessage()+"\n");}catch(Exceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar as configurações de porta ADSL: "+shelf.getIp()+"(unit-"+c.getSlot()+")\n"+ex.getMessage()+"\n");}}System.out.println("Tamanho da lista: "+ports.size());Dao<Port>dao=newDao<Port>(HibernateCore.getSession(),Port.class);for(Portp:ports){try{p.getId().setShelf(shelf);HibernateCore.beginTransaction();dao.saveOrUpdate(p);HibernateCore.commitTransaction();}catch(DaoExceptionex){Logger.getLogger(ThreadInventory.class.getName()).log(Level.SEVERE,null,ex);}}}publicStringuploadBackup(){Stringfile=shelf.getIp()+".tar";try{shelfFunc.upload("/cfgm/configuration","milegate_backup/"+file);}catch(MilegateExceptionex){Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}returnfile;}privatevoidpersistenceCards(){DaoCarddao=newDaoCard(HibernateCore.getSession());if(cards.size()!=0){List<Card>oldCards=dao.getCardsByIp(shelf.getIp());for(Cardb:oldCards){try{HibernateCore.beginTransaction();dao.getDaoGeneric().delete(b);HibernateCore.commitTransaction();}catch(DaoExceptionex){Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}}for(Cardc:cards){try{c=shelfFunc.getCardFullInformation(c);}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: "+shelf.getIp()+"(unit-"+c.getSlot()+")\n"+ex.getMessage()+"\n");}try{c.setShelf(shelf);c.setLastUpdate(Calendar.getInstance());HibernateCore.beginTransaction();dao.getDaoGeneric().save(c);HibernateCore.commitTransaction();}catch(DaoExceptionex){Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}}}}publicbooleanisHaveSuad(List<Card>cards){for(Cardc:cards){if(c.getName().matches("SUAD.*")){returntrue;}}returnfalse;}privatevoidpersistenceProfiles(){ProfileAdslFunctionprofileAdslFunction=newProfileAdslFunction();ProfileChanFunctionprofileChanFunction=newProfileChanFunction();Dao<ProfileMilegate>dao=newDao<ProfileMilegate>(HibernateCore.getSession(),ProfileMilegate.class);List<ProfileMilegate>profiles=null;try{profiles=shelfFunc.getProfiles();}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: "+shelf.getIp()+" (profile)\n"+ex.getMessage()+"\n");}for(ProfileMilegatep:profiles){Filefile=newFile("/home/paulo/"+shelf.getIp()+"/");file.mkdirs();if(p.getTypeProfile().equals("Adsl2PortProfile")){p.setFileName("/home/paulo/"+shelf.getIp()+"/"+p.getName());try{shelfFunc.upload("/cfgm/Profile",p.getFileName());}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: "+shelf.getIp()+" (profile)\n"+ex.getMessage()+"\n");}p.setShelf(shelf);p=profileAdslFunction.validateAdslProfile(p);HibernateCore.beginTransaction();HibernateCore.getSession().flush();try{dao.save(p);}catch(DaoExceptionex){Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}HibernateCore.commitTransaction();HibernateCore.getSession().flush();}elseif(p.getTypeProfile().equals("Adsl2ChanProfile")){p.setFileName("/home/paulo/"+shelf.getIp()+"/"+p.getName());try{shelfFunc.upload("/cfgm/Profile",p.getFileName());}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: "+shelf.getIp()+"(profile : "+p.getName()+")\n"+ex.getMessage()+"\n");}p.setShelf(shelf);p=profileChanFunction.validateChanProfile(p);HibernateCore.beginTransaction();try{dao.save(p);}catch(DaoExceptionex){Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}HibernateCore.commitTransaction();HibernateCore.getSession().flush();}}}publicbooleanconfigureFtpServer(){try{shelfFunc.setFtpServer(getFtpserver(),getFtpusername(),getFtppassword());returntrue;}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao configurar o servidor ftp do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}returnfalse;}publicvoidrun(){try{core.connect(shelf.getIp(),23);core.configureModeDisplayXml();try{cards=shelfFunc.getCardsBrief();}catch(MilegateExceptionex){Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}this.persistenceCards();if(isHaveSuad(cards)){if(this.configureFtpServer()){this.persistenceProfiles();}// Portas ADSLFilefile=newFile("/home/paulo/milegate_backup/"+this.uploadBackup());if(file.exists()){System.out.println(file.getAbsolutePath());this.persistenceAdslPortsFromFileBackup(file.getAbsolutePath());}else{Log.logger.severe("[MILEGATE] - falha ao gerar o arquivo de backup: "+shelf.getIp()+"\n");}}core.disconnect();System.out.println("Executou no elemento:"+shelf.getIp());}catch(MilegateConnectionExceptionex){Log.logger.severe("[MILEGATE] - erro ao conectar no elemento: "+shelf.getIp()+"\n"+ex.getMessage()+"\n");}}publicStringgetFtppassword(){returnftppassword;}publicvoidsetFtppassword(Stringftppassword){this.ftppassword=ftppassword;}publicStringgetFtpserver(){returnftpserver;}publicvoidsetFtpserver(Stringftpserver){this.ftpserver=ftpserver;}publicStringgetFtpusername(){returnftpusername;}publicvoidsetFtpusername(Stringftpusername){this.ftpusername=ftpusername;}}
Pedrosa
Cara como esta o seu hibernate.cfg.xml?
Analisando o seu codigo para ajustar para o uso do Spring é tranquilo, vc usa o um DAO generico vc mata tudo em lugar só, na minha opinião vale a pena perder um tempinho agora e fazer a coisa nobre e evitar dores de cabeça lá na frente:
No seu metodo vc anota que ele é uma Transação, simples assim, inversão de controle.
pauloperes
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><propertyname="connection.url">jdbc:postgresql://10.200.17.25/access</property><propertyname="connection.username">access</property><propertyname="connection.driver_class">org.postgresql.Driver</property><propertyname="dialect">org.hibernate.dialect.PostgreSQLDialect</property><propertyname="connection.password">access</property><propertyname="hibernate.c3p0.max_size">60</property><propertyname="hibernate.c3p0.min_size">1</property><propertyname="hibernate.c3p0.timeout">5000</property><propertyname="hibernate.c3p0.max_statements">200</property><propertyname="hibernate.c3p0.idle_test_period">3000</property><propertyname="hibernate.c3p0.acquire_increment">1</property><mappingclass="br.com.model.Card"/><mappingclass="br.com.model.City"/><mappingclass="br.com.model.Collaborator"/><mappingclass="br.com.model.Shelf"/><mappingclass="br.com.model.Port"/><mappingclass="br.com.model.ProfileMilegate"/><mappingclass="br.com.model.MilegateAdslProfileConfig"/><mappingclass="br.com.model.MilegateChanProfileConfig"/><mappingclass="br.com.model.PortPK"/><mappingclass="br.com.model.Report"/><mappingclass="br.com.model.CardTypeZhone"/><mappingclass="br.com.model.CardTypeZhonePK"/><mappingclass="br.com.model.EmailCollaborator"/><mappingclass="br.com.model.EmailBulk"/><mappingclass="br.com.model.ReportCollaborator"/></session-factory></hibernate-configuration>
Quando vc diz usar a anotação de transação, eu faco isto no meu método save do dao?
Outra coisa, com relação ao fechamento das sessões, preciso fazer na minha classe tread?
Att,
Pedrosa
Não, vc anota o metodo que realmente é uma transação, no seu caso o por exemplo persistenceCards o save é do Dao.
O fechamento das conexoes fica para o Spring fazer debaixo dos panos.
Uma ourtra coisa que notei é que se der Exception vc nao faz rollback, e advinhe que faz isso para vc?
pauloperes
mantem as conexoes ativas certo? que mancada…
pauloperes
Aproveitando o topico acho que o meu pool de threads também está dando pau, vejam como esta:
packagemilegateinventory;importbr.com.dao.DaoShelf;importbr.com.gvt.loglib.core.Log;importbr.com.gvt.milegateinventory.core.ThreadInventory;importbr.com.hibernate.HibernateCore;importbr.com.model.Shelf;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.Properties;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;importjava.util.logging.Level;importjava.util.logging.Logger;/** * * @author paulo */publicclassMain{ExecutorServicethreadPool;publicMain(intmaxThreads){threadPool=Executors.newFixedThreadPool(maxThreads);}publicvoidstart(List<Shelf>shelves,intmaxThreads,Stringftpserver,Stringftpusername,Stringftppassword)throwsIOException{List<Future>futures=newArrayList<Future>();for(Shelfs:shelves){futures.add(threadPool.submit(newThreadInventory(s,ftpserver,ftpusername,ftppassword)));}intcountDone=0;System.out.println("Numero de processos: "+futures.size());threadPool.shutdown();}publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException{intmaxThreads=0;Stringftpserver=null;Stringftpusername=null;Stringftppassword=null;Propertiesproperties=newProperties();try{properties.load(newFileInputStream(args[0]));maxThreads=Integer.parseInt(properties.getProperty("max_threads"));ftpserver=properties.getProperty("ftpserver");ftpusername=properties.getProperty("ftpusername");ftppassword=properties.getProperty("ftppassword");}catch(FileNotFoundExceptionex){Log.logger.severe("Erro ao carregar o arquivo de configurações do programa\n"+ex.getMessage()+"\n");System.exit(1);}catch(IOExceptionex){Log.logger.severe("Erro ao carregar o arquivo de configurações do programa\n"+ex.getMessage()+"\n");System.exit(1);}DaoShelfdaoShelf=newDaoShelf(HibernateCore.getSession());List<Shelf>shelves=daoShelf.listByModel("Milegate2500");Mainmain=newMain(maxThreads);main.start(shelves,maxThreads,ftpserver,ftpusername,ftppassword);}}