Numero de conexoes com o banco

14 respostas
pauloperes

Ola a todos,

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?

14 Respostas

bruno_savi

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

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

https://www.hibernate.org/43.html

pauloperes

Tempo realmente ta curto, rsrsrs

pauloperes

Detalhe a aplicacao nao é Web

Pedrosa

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.
 */
package br.com.gvt.milegateinventory.core;

import br.com.dao.Dao;
import br.com.dao.DaoCard;
import br.com.exception.DaoException;
import br.com.gvt.loglib.core.Log;
import br.com.gvt.milegate.core.Core;
import br.com.gvt.milegate.exception.MilegateConnectionException;
import br.com.gvt.milegate.exception.MilegateException;
import br.com.gvt.milegate.function.BackupAdsl;
import br.com.gvt.milegate.function.PortAdslFunc;
import br.com.gvt.milegate.function.ProfileAdslFunction;
import br.com.gvt.milegate.function.ProfileChanFunction;
import br.com.gvt.milegate.function.ShelfFunc;
import br.com.gvt.milegate.function.UnitFunc;
import br.com.gvt.milegate.telnet.TelnetCore;
import br.com.hibernate.HibernateCore;
import br.com.model.Card;
import br.com.model.Port;
import br.com.model.ProfileMilegate;
import br.com.model.Shelf;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.JDOMException;

/**
 *
 * @author paulo
 */
public class ThreadInventory implements Runnable {

    private Shelf shelf;
    private TelnetCore telnetCore = new TelnetCore();
    private Core core = new Core(telnetCore);
    private ShelfFunc shelfFunc = new ShelfFunc(telnetCore);
    private UnitFunc unitFunc = new UnitFunc(telnetCore);
    private List<Card> cards = null;
    private PortAdslFunc portAdslFunc = new PortAdslFunc(telnetCore);
    private Dao<Port> daoPort;
    private Dao<Card> daoCard;
    private Dao<ProfileMilegate> daoProfile;
    private String ftpserver;
    private String ftpusername;
    private String ftppassword;

    public ThreadInventory(Shelf shelf) {
        this.shelf = shelf;
    }

    public ThreadInventory(Shelf shelf, String ftpserver, String ftpusername, String ftppassword) {
        this.shelf = shelf;
        this.ftpserver = ftpserver;
        this.ftpusername = ftpusername;
        this.ftppassword = ftppassword;
    }

    public void persistenceAdslPortsFromFileBackup(String file) {        
        BackupAdsl backupAdsl = new BackupAdsl();
        List<Port> ports = new ArrayList<Port>();
        for (Card c : cards) {
            try {
                ports.addAll(backupAdsl.getAdslConfigurationBySlot(c, file));
            } catch (JDOMException ex) {
                Log.logger.severe("[MILEGATE] - erro ao recuperar as configurações de porta ADSL: " + shelf.getIp() + "(unit-" + c.getSlot() + ")\n" + ex.getMessage() + "\n");
            } catch (IOException ex) {
                Log.logger.severe("[MILEGATE] - erro ao recuperar as configurações de porta ADSL: " + shelf.getIp() + "(unit-" + c.getSlot() + ")\n" + ex.getMessage() + "\n");
            } catch (Exception ex) {
                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 = new Dao<Port>(HibernateCore.getSession(), Port.class);
        for (Port p : ports) {
            try {                
                p.getId().setShelf(shelf);
                HibernateCore.beginTransaction();
                dao.saveOrUpdate(p);
                HibernateCore.commitTransaction();
            } catch (DaoException ex) {
                Logger.getLogger(ThreadInventory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public String uploadBackup() {
        String file = shelf.getIp() + ".tar";
        try {
            shelfFunc.upload("/cfgm/configuration", "milegate_backup/" + file);
        } catch (MilegateException ex) {
            Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
        }
        return file;
    }

    private void persistenceCards() {
        DaoCard dao = new DaoCard(HibernateCore.getSession());


        if (cards.size() != 0) {
            List<Card> oldCards = dao.getCardsByIp(shelf.getIp());

            for (Card b : oldCards) {
                try {
                    HibernateCore.beginTransaction();
                    dao.getDaoGeneric().delete(b);
                    HibernateCore.commitTransaction();
                } catch (DaoException ex) {
                    Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
                }
            }

            for (Card c : cards) {
                try {
                    c = shelfFunc.getCardFullInformation(c);
                } catch (MilegateException ex) {
                    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 (DaoException ex) {
                    Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
                }

            }

        }

    }

    public boolean isHaveSuad(List<Card> cards) {
        for (Card c : cards) {
            if (c.getName().matches("SUAD.*")) {
                return true;
            }
        }
        return false;
    }

    private void persistenceProfiles() {
        ProfileAdslFunction profileAdslFunction = new ProfileAdslFunction();
        ProfileChanFunction profileChanFunction = new ProfileChanFunction();


        Dao<ProfileMilegate> dao = new Dao<ProfileMilegate>(HibernateCore.getSession(), ProfileMilegate.class);

        List<ProfileMilegate> profiles = null;
        try {
            profiles = shelfFunc.getProfiles();
        } catch (MilegateException ex) {
            Log.logger.severe("[MILEGATE] - erro ao recuperar os dados do elemento: " + shelf.getIp() + " (profile)\n" + ex.getMessage() + "\n");
        }

        for (ProfileMilegate p : profiles) {
            File file = new File("/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 (MilegateException ex) {
                    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 (DaoException ex) {
                    Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
                }
                HibernateCore.commitTransaction();
                HibernateCore.getSession().flush();
            } else if (p.getTypeProfile().equals("Adsl2ChanProfile")) {
                p.setFileName("/home/paulo/" + shelf.getIp() + "/" + p.getName());
                try {
                    shelfFunc.upload("/cfgm/Profile", p.getFileName());
                } catch (MilegateException ex) {
                    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 (DaoException ex) {
                    Log.logger.severe("[HIBERNATE] - erro ao gravar os dados do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
                }
                HibernateCore.commitTransaction();
                HibernateCore.getSession().flush();
            }
        }

    }

    public boolean configureFtpServer() {
        try {
            shelfFunc.setFtpServer(getFtpserver(), getFtpusername(), getFtppassword());
            return true;
        } catch (MilegateException ex) {
            Log.logger.severe("[MILEGATE] - erro ao configurar o servidor ftp do elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
        }
        return false;
    }

    public void run() {

        try {
            core.connect(shelf.getIp(), 23);
            core.configureModeDisplayXml();

            try {
                cards = shelfFunc.getCardsBrief();
            } catch (MilegateException ex) {
                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 ADSL
                File file = new File("/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 (MilegateConnectionException ex) {
            Log.logger.severe("[MILEGATE] - erro ao conectar no elemento: " + shelf.getIp() + "\n" + ex.getMessage() + "\n");
        }
    }

    public String getFtppassword() {
        return ftppassword;
    }

    public void setFtppassword(String ftppassword) {
        this.ftppassword = ftppassword;
    }

    public String getFtpserver() {
        return ftpserver;
    }

    public void setFtpserver(String ftpserver) {
        this.ftpserver = ftpserver;
    }

    public String getFtpusername() {
        return ftpusername;
    }

    public void setFtpusername(String ftpusername) {
        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:

Por exemplo isso:

HibernateCore.beginTransaction();   
dao.saveOrUpdate(p);   
HibernateCore.commitTransaction();

Vira:

dao.saveOrUpdate(p);

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>
        <property name="connection.url">jdbc:postgresql://10.200.17.25/access</property>
        <property name="connection.username">access</property>
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="connection.password">access</property>

        <property name="hibernate.c3p0.max_size">60</property>
        <property name="hibernate.c3p0.min_size">1</property>
        <property name="hibernate.c3p0.timeout">5000</property>
        <property name="hibernate.c3p0.max_statements">200</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <property name="hibernate.c3p0.acquire_increment">1</property>


        <mapping class="br.com.model.Card"/>
        <mapping class="br.com.model.City"/>
        <mapping class="br.com.model.Collaborator"/>
        <mapping class="br.com.model.Shelf"/>
        <mapping class="br.com.model.Port"/>
        <mapping class="br.com.model.ProfileMilegate"/>
        <mapping class="br.com.model.MilegateAdslProfileConfig"/>
        <mapping class="br.com.model.MilegateChanProfileConfig"/>
        <mapping class="br.com.model.PortPK"/>
        <mapping class="br.com.model.Report"/>
        <mapping class="br.com.model.CardTypeZhone"/>
        <mapping class="br.com.model.CardTypeZhonePK"/>
        <mapping class="br.com.model.EmailCollaborator"/>
        <mapping class="br.com.model.EmailBulk"/>
        <mapping class="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:

package milegateinventory;

import br.com.dao.DaoShelf;
import br.com.gvt.loglib.core.Log;
import br.com.gvt.milegateinventory.core.ThreadInventory;
import br.com.hibernate.HibernateCore;
import br.com.model.Shelf;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author paulo
 */
public class Main {

    ExecutorService threadPool;

    public Main(int maxThreads) {
        threadPool = Executors.newFixedThreadPool(maxThreads);
    }

    public void start(List<Shelf> shelves, int maxThreads, String ftpserver, String ftpusername, String ftppassword) throws IOException {

        List<Future> futures = new ArrayList<Future>();
        for (Shelf s : shelves) {
            futures.add(threadPool.submit(new ThreadInventory(s, ftpserver, ftpusername, ftppassword)));
        }

        int countDone = 0;
        System.out.println("Numero de processos: " + futures.size());
        
        threadPool.shutdown();
        
    }

    public static void main(String[] args) throws FileNotFoundException, IOException {
        int maxThreads = 0;
        String ftpserver = null;
        String ftpusername = null;
        String ftppassword = null;
        Properties properties = new Properties();

        try {
            properties.load(new FileInputStream(args[0]));
            maxThreads = Integer.parseInt(properties.getProperty("max_threads"));
            ftpserver = properties.getProperty("ftpserver");
            ftpusername = properties.getProperty("ftpusername");
            ftppassword = properties.getProperty("ftppassword");
        } catch (FileNotFoundException ex) {
            Log.logger.severe("Erro ao carregar o arquivo de configurações do programa\n" + ex.getMessage() + "\n");
            System.exit(1);
        } catch (IOException ex) {
            Log.logger.severe("Erro ao carregar o arquivo de configurações do programa\n" + ex.getMessage() + "\n");
            System.exit(1);
        }

        DaoShelf daoShelf = new DaoShelf(HibernateCore.getSession());
        List<Shelf> shelves = daoShelf.listByModel("Milegate2500");        
        Main main = new Main(maxThreads);
        main.start(shelves, maxThreads, ftpserver, ftpusername, ftppassword);
    }
}
Criado 25 de novembro de 2009
Ultima resposta 25 de nov. de 2009
Respostas 14
Participantes 3