Precisa de código para criar um conjunto de ligações em java

Precisa de um código para criar o conjunto de ligações em java? Como é que nos certificamos que o conjunto de ligações não devolve o mesmo objecto que já está em uso? Como acontece se o cliente fechou a conexão depois de tirá-lo da piscina de conexão?

actualização 1:

quero criar isto em termos Java simples e quero ver como funciona em multithreading Env. Quero dizer que métodos seriam sincronizados e que não são. Também esta classe seria uma classe pública? Se sim, então qualquer pode-se aceder a esta classe e reiniciar o conjunto de ligações?

actualização 2:

Tenho um código como em baixo. Mas não sei como "fechar uma ligação vinda de uma piscina devolve-a à piscina, ela não fecha a ligação fisicamente." Também não entendi isso " porque se uma conexão foi emprestada da piscina e ainda não foi devolvida, ela não está "disponível" e não pode ser redistribuída para outro cliente da piscina."

import java.util.*;
import java.sql.*;

class ConnectionPoolManager
{

 String databaseUrl = "jdbc:mysql://localhost:3306/myDatabase";
 String userName = "userName";
 String password = "userPass";

 Vector connectionPool = new Vector();

 public ConnectionPoolManager()
 {
  initialize();
 }

 public ConnectionPoolManager(
  //String databaseName,
  String databaseUrl,
  String userName,
  String password
  )
 {
  this.databaseUrl = databaseUrl;
  this.userName = userName;
  this.password = password;
  initialize();
 }

 private void initialize()
 {
  //Here we can initialize all the information that we need
  initializeConnectionPool();
 }

 private void initializeConnectionPool()
 {
  while(!checkIfConnectionPoolIsFull())
  {
   System.out.println("Connection Pool is NOT full. Proceeding with adding new connections");
   //Adding new connection instance until the pool is full
   connectionPool.addElement(createNewConnectionForPool());
  }
  System.out.println("Connection Pool is full.");
 }

 private synchronized boolean checkIfConnectionPoolIsFull()
 {
  final int MAX_POOL_SIZE = 5;

  //Check if the pool size
  if(connectionPool.size() < 5)
  {
   return false;
  }

  return true;
 }

 //Creating a connection
 private Connection createNewConnectionForPool()
 {
  Connection connection = null;

  try
  {
   Class.forName("com.mysql.jdbc.Driver");
   connection = DriverManager.getConnection(databaseUrl, userName, password);
   System.out.println("Connection: "+connection);
  }
  catch(SQLException sqle)
  {
   System.err.println("SQLException: "+sqle);
   return null;
  }
  catch(ClassNotFoundException cnfe)
  {
   System.err.println("ClassNotFoundException: "+cnfe);
   return null;
  }

  return connection;
 }

 public synchronized Connection getConnectionFromPool()
 {
  Connection connection = null;

  //Check if there is a connection available. There are times when all the connections in the pool may be used up
  if(connectionPool.size() > 0)
  {
   connection = (Connection) connectionPool.firstElement();
   connectionPool.removeElementAt(0);
  }
  //Giving away the connection from the connection pool
  return connection;
 }

 public synchronized void returnConnectionToPool(Connection connection)
 {
  //Adding the connection from the client back to the connection pool
  connectionPool.addElement(connection);
 }

 public static void main(String args[])
 {
  ConnectionPoolManager ConnectionPoolManager = new ConnectionPoolManager();
 }

}
Author: Bill the Lizard, 2010-05-13

7 answers

Precisa de um código para criar o conjunto de ligações em java?

Não tem a certeza de que a questão é, mas não de criar mais um pool de conexão, use uma solução existente, como C3P0, Apache DBCP, Proxool ou BoneCP (um novo jogador em campo). Eu usaria C3P0.

Como é que nos certificamos que o conjunto de ligações não devolve o mesmo objecto que já está em uso?

Porque se uma ligação foi emprestado do pool e ainda não devolvido, ele simplesmente não está no pool e não pode ser atribuído a outro cliente do pool (os recursos são removidos do pool até que eles são devolvidos).

Como é que acontece se o cliente fechou a ligação depois de a tirar do grupo de ligação?

A ligação que um cliente obtém de uma piscina não é realmente um java.sql.Connection, é um invólucro (um proxy) para um java.sql.Connection Isso personaliza o comportamento de alguns métodos. O método close() é um deles e não fecha a instância Connection mas devolve - a à piscina.

 45
Author: Pascal Thivent, 2010-05-13 11:50:37
Não escrevas o teu. Existem muitos bibliotecários lá fora que farão isso por você que são de código aberto e fácil de usar e terão resolvido todos os problemas que você vai encontrar tentando fazê-lo você mesmo.

Aqui está um exemplo simples que usa o Apache Commons DBCP e o Commons Pool:

Primeiro criou uma fonte de dados.

javax.sql.DataSource source = new org.apache.commons.dbcp.BasicDataSource();
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUsername("username");
source.setPassword("password");
source.setUrl("jdbc:mysql://localhost:3306/myDatabase");
Uma vez que você tem um DataSource, é fácil obter uma conexão do pool.
java.sql.Connection connection = source.getConnection();
Se fecharmos a ligação, devolvemo-la. a piscina para ti.
connection.close();
 13
Author: Ryan Elkins, 2010-05-13 14:47:44
Espero que este código-fonte ajude. http://jagadeeshmanne.blogspot.in/2014/03/connection-pool-in-java-jdbc.html

Configuração.java

package com.jmanne.utils;

public class Configuration {

 public String DB_USER_NAME ;

 public String DB_PASSWORD ;

 public String DB_URL;

 public String DB_DRIVER;

 public Integer DB_MAX_CONNECTIONS;

 public Configuration(){
  init();
 }

 private static Configuration configuration = new Configuration();

 public static Configuration getInstance(){ 
  return configuration;
 }

 private void init(){
  DB_USER_NAME = "root"
  DB_PASSWORD = "root"
  DB_URL = "jdbc:mysql://localhost:3306/jmanne"
  DB_DRIVER = "com.mysql.jdbc.Driver"
  DB_MAX_CONNECTIONS = 5
 }     
}

Jdbconnectionpool.java

package com.jmanne.db;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.jmanne.utils.Configuration;
import com.mysql.jdbc.Connection;

public class JdbcConnectionPool {

 List<connection> availableConnections = new ArrayList<connection>();

 public JdbcConnectionPool()
 {
  initializeConnectionPool();
 }

 private void initializeConnectionPool()
 {
  while(!checkIfConnectionPoolIsFull())
  {
   availableConnections.add(createNewConnectionForPool());
  }
 }

 private synchronized boolean checkIfConnectionPoolIsFull()
 {
  final int MAX_POOL_SIZE = Configuration.getInstance().DB_MAX_CONNECTIONS;

  if(availableConnections.size() < MAX_POOL_SIZE)
  {
   return false;
  }

  return true;
 }

 //Creating a connection
 private Connection createNewConnectionForPool()
 {
  Configuration config = Configuration.getInstance();
  try {
   Class.forName(config.DB_DRIVER);
   Connection connection = (Connection) DriverManager.getConnection(
     config.DB_URL, config.DB_USER_NAME, config.DB_PASSWORD);
   return connection;
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return null;

 }

 public synchronized Connection getConnectionFromPool()
 {
  Connection connection = null;
  if(availableConnections.size() > 0)
  {
   connection = (Connection) availableConnections.get(0);
   availableConnections.remove(0);
  }
  return connection;
 }

 public synchronized void returnConnectionToPool(Connection connection)
 {
  availableConnections.add(connection);
 }
}

DataSource.java

package com.jmanne.db;

import java.sql.SQLException;

import com.mysql.jdbc.Connection;

public class DataSource {

 static JdbcConnectionPool pool = new JdbcConnectionPool();

 public static Connection getConnection() throws ClassNotFoundException, SQLException{
  Connection connection = pool.getConnectionFromPool();
  return connection;
 }

 public static void returnConnection(Connection connection) {
  pool.returnConnectionToPool(connection);
 }
}
 11
Author: Jagadeesh, 2015-01-07 14:14:18
Basta usar semáforos. Idealmente, o que deve fazer é usar CP3O ou DBCP como conjunto de ligações. Agora podes acelerar a ligação com base no semáforo. Cada vez que o fazes, adquires e em cada Release Libertas-o de um semáforo. Mais sobre semáforos estão seguros.
 6
Author: Princesh, 2012-11-01 21:21:34

Utilize um dos existentes, por exemplo Apache DBCP

As ligações devolvidas pelo pool são muitas vezes proxies que "ignoram" a chamada para {[[0]} a partir da aplicação. Quando as conexões são devolvidas à piscina, elas podem ser reutilizadas. As piscinas também fecham e reabrem automaticamente, se necessário.

 4
Author: mhaller, 2010-05-13 11:09:10

Se a sua aplicação correr num servidor, então configure como fonte de dados, onde o servidor irá cuidar do Pooling ou então se um cliente Java simples, então use o Apache DBCP (se para a base de dados) ou então use o Apache Commons Pooling API Veja aqui: Apache Commons

 2
Author: Phani, 2010-05-13 11:56:54

Um argumento para rolar o seu próprio connpool é a configuração e frascos adicionais que são evitados. Eu concordo que você precisa permitir as interfaces de terceiros para que você possa trocar em um connpool maduro, mas ter sua própria solução minúscula pode ter o seu lugar. Vetor de auto-limpeza com bloco sincronizado e uma embalagem de conn com close() marcando o conn como disponível funciona muito bem para aplicações servlet.

 2
Author: Jonathan Cole, 2012-08-09 03:43:51