[RESOLVIDO] Dùvida de Implementação de DAO em ambiente Multi-thread

Olá.

Eu tenho uma aplicação em um computador, que interage com um equipamento. Nessa aplicação 3 threads. Uma insere as configurações do equipamento (recebida de um servidor via WebService) no banco. Uma thread pega essas informações e usa pra configurar o rquipamento e receber respostas dele, essas respostas são colocadas num banco. E uma terceira thread que lê essas respostas do banco e manda de volta pro servidor (Web Services).

Atualmente essa aplicação tem 2 classes que manipulam o banco. Uma classe Operation, que é um Singleton, que gerencia a conexão e faz os inserts, updates e deletes. E uma classe Query que usa a classe Operation para pegar a conexão e relaizas as queries (Selects).

Eu vou atualizar isso. Implementar o padrão DAO. As classes DAO não são um grande problema, já tenho a divisão delas bem formadas na minha cabeça. Meu problema são os seguintes:

Primeiro, conexão com o banco. Eu pensei em criar uma classe ConnMAnager (Singleton) que inicializa o banco (cria as tables, caso não existam, e sim isso é necessário) conecta, e devolve a conexão através de um método estático. É a melhor solução? Ou deveria fazer uma ConnectionFactory e devolver uma conexão nova? (O banco que eu uso é o postgresql e é threadsafe).

Segundo: Em relação ao uso dos DAO. Eu devo na chamado dos métodos criar um novo DAO ? Ou criar uma instancia do DAO para a classe e inicializar no contrutor? OU ainda, fazer os DAO Singleton?

A parte do uso dos DAO é a maior dúvida. O código de cada um tá bem pensado, o uso é que me confunde.

Quando você precisar trabalhar com multi-threading procure evitar situações de concorrência. Para as conexões com o banco de dados, procure utilizar um pool de conexões, como o c3p0. Sempre que alguém precisar de uma conexão, você busca no pool que ele decide se reaproveita uma conexão ou cria uma nova. Você só precisa configurar os dados da conexão e o tamanho do pool.

No caso dos DAO. Eu forneceria uma conexão no construtor do DAO, e construiria um novo DAO para cada requisição. Isso evita gargalos desnecessários.

Seria mesmo necessário um pool de conexões, mesmo tendo um número limitado de threads? É fato que existirão no máximo 5 threads. sendo 2 duas rodando em task (de x em x segundos). A thread que insere informações novas no banco é pouco chamada, (só quando solicitado pelo usuário).

Certo. E em relação à como fazer a chamada do DAO pela classe? Por exemplo, a classe principal que fica em loop. Eu devo instancia um novo dao dentro do loop, e instanciar um novo à cada loop, ou devo instanciar um dao na construção da classe e usar essa instancia ?

[quote=rock-skull]Seria mesmo necessário um pool de conexões, mesmo tendo um número limitado de threads? É fato que existirão no máximo 5 threads. sendo 2 duas rodando em task (de x em x segundos). A thread que insere informações novas no banco é pouco chamada, (só quando solicitado pelo usuário).

Certo. E em relação à como fazer a chamada do DAO pela classe? Por exemplo, a classe principal que fica em loop. Eu devo instancia um novo dao dentro do loop, e instanciar um novo à cada loop, ou devo instanciar um dao na construção da classe e usar essa instancia ?[/quote]

Pense no GC. Se você ficar criando DAOs dentro do loop você vai gastar um bom tempo de processamento com o seu GC coletando esses objetos de vida curta. Em compensação, se você criar apenas 1 você economiza recursos consideráveis, pois a criação do objeto ocorre apenas 1 vez e ele será coletado somente no final da vida da classe. Nesse caso, se você puder aproveitar a conexão também é bom, e é melhor ainda se dentro do DAO você fizer cache dos seus PreparedStatement’s.

É, nisso que eu tava pensando.

Obrigado por esclarecer essas coisas. A parte de divisão dos DAO’s, métodos e etc, ficou bem claro lendo coisas na internet, mas essa parte de chamadas e instancias tinha ficado meio confusa.

Só como exemplo então ficaria algo do gênero?

ConnectionManager.java:

public class ConnectionManager{ public static Connection getConnection(){ //return connection from pool } }
DAOXXX.java

public class DAOXXX{
       public DAOXXX(Connection con){
              this.connection = con;
       }
      //DAO METHODS
}

Loop.java

public class Loop implements Runnable{
       private DAOXXX  daoXXX = new DAOXXX(ConnectionManager.getConnection());
       @Override
       public void run(){
           //do loop stuff
           daoXXX.daoMehtod();
       }
}

É isso ?

Sim. É isso mesmo.

Valeu cara.

Obrigado pela ajuda.