wake-up-neo.com

Code zum Erstellen des Verbindungspools in java

Benötigen Sie Code, um den Verbindungspool in Java zu erstellen? Wie stellen wir sicher, dass der Verbindungspool nicht dasselbe Objekt zurückgibt, das bereits verwendet wird? Wie passiert es, wenn der Client die Verbindung geschlossen hat, nachdem er sie aus dem Verbindungspool entfernt hat?

Update 1:

Ich möchte dies in Simple Java) erstellen und sehen, wie es in Multithreading Env funktioniert. Ich meine, welche Methoden synchronisiert werden und welche nicht. Auch wird diese Klasse eine öffentliche Klasse sein Wenn ja, kann jemand auf diese Klasse zugreifen und den Verbindungspool neu initialisieren.

Update 2:

Ich habe einen Code wie unten. Aber ich weiß nicht, wie "das Schließen einer Verbindung, die aus einem Pool stammt, sie in den Pool zurückgibt, die Verbindung physikalisch nicht schließt." Außerdem habe ich Folgendes nicht verstanden: "Wenn eine Verbindung aus dem Pool ausgeliehen und noch nicht zurückgegeben wurde, ist sie nicht" verfügbar "und kann nicht an einen anderen Client des Pools weitergegeben werden."

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();
 }

}
30
mohan

Benötigen Sie Code, um den Verbindungspool in Java zu erstellen?

Sie sind sich nicht sicher, was die Frage ist, aber erstellen Sie keinen weiteren Verbindungspool. Verwenden Sie eine vorhandene Lösung wie C3P , Apache DBCP , Proxool oder - BoneCP (ein neuer Spieler in diesem Feld). Ich würde C3P0 verwenden.

Wie stellen wir sicher, dass der Verbindungspool nicht dasselbe Objekt zurückgibt, das bereits verwendet wird?

Denn wenn eine Verbindung aus dem Pool ausgeliehen und noch nicht zurückgegeben wurde, befindet sie sich nur nicht im Pool und kann keinem anderen Client des Pools zugewiesen werden (Ressourcen werden aus dem Pool entfernt, bis sie zurückgegeben werden).

Wie passiert es, wenn der Client die Verbindung geschlossen hat, nachdem er sie aus dem Verbindungspool entfernt hat?

Die Verbindung, die ein Client aus einem Pool erhält, ist nicht wirklich ein Java.sql.Connection , es ist ein Wrapper (ein Proxy) für ein Java.sql.Connection , das angepasst wird das Verhalten einiger Methoden. Die Methode close() ist eine davon und schließt die Instanz Connection nicht , sondern gibt sie an den Pool zurück.

46
Pascal Thivent

Schreib nicht deine eigenen. Es gibt viele Bibliothekare, die dies für Sie tun, die Open Source und einfach zu bedienen sind und alle Probleme gelöst haben, auf die Sie stoßen, wenn Sie versuchen, es selbst zu machen.

Hier ist ein einfaches Beispiel, das Apaches Commons DBCP und Commons Pool verwendet:

Richten Sie zuerst eine DataSource ein.

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");

Sobald Sie eine DataSource haben, ist es einfach, eine Verbindung aus dem Pool zu erhalten.

Java.sql.Connection connection = source.getConnection();

wenn Sie die Verbindung beenden, wird sie für Sie in den Pool zurückgeführt.

connection.close();
13
Ryan Elkins

Ich hoffe, dieser Quellcode hilft http://jagadeeshmanne.blogspot.in/2014/03/connection-pool-in-Java-jdbc.html

Configuration.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
 }     
}

JdbcConnectionPool.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);
 }
}
12
Jagadeesh

Verwenden Sie einfach Semaphoren. Verwenden Sie im Idealfall CP3O oder DBCP als Ihr Verbindungspool. Jetzt können Sie Ihre Verbindung basierend auf Semaphore drosseln.

Jedes Mal, wenn Sie Get ausführen, erwerben Sie und geben es auf jedem Release von Semaphore frei. Mehr über Semaphoren sind threadsicher.

6
Princesh

Verwenden Sie eines der vorhandenen, z. Apache DBCP

Die vom Pool zurückgegebenen Verbindungen sind häufig Proxys, die den Aufruf von close() aus der Anwendung "ignorieren". Wenn die Verbindungen zum Pool zurückgegeben werden, können sie wiederverwendet werden. Pools werden bei Bedarf automatisch geschlossen und wieder geöffnet.

4
mhaller

Wenn Ihre Anwendung auf einem Server ausgeführt wird, konfigurieren Sie sie als Datenquelle, auf der der Server das Pooling übernimmt, oder verwenden Sie Apache DBCP (wenn in der Datenbank) oder einen einfachen Java Client) Apache Commons Pooling API Siehe hier: Apache Commons

2
Phani

Ein Argument für das Rolling Ihres eigenen Connpools sind die Konfiguration und zusätzliche Jars, die vermieden werden. Ich bin damit einverstanden, dass Sie die Schnittstellen von Drittanbietern aktivieren müssen, damit Sie einen ausgereiften Connpool austauschen können, aber eine eigene winzige Lösung kann ihren Platz haben. Selbstreinigender Vektor mit synchronisiertem Block und einem Conn-Wrapper mit close (), der den Conn als verfügbar markiert, eignet sich sehr gut für Servlet-Apps.

2
Jonathan Cole

Ich habe eine Lösung für das gleiche, um ein Verbindungspool-Dienstprogramm zu erstellen, mit dem Sie einen Pool mit der Standardgröße 10 erstellen können.

@Component public class ConnectionPool {private static final Logger logger = LoggerFactory.getLogger (ConnectionPool.class); private static final int MAX_POOL_SIZE_LIMIT = 10; private BlockingQueue activeConnectinoQueue = new LinkedBlockingQueue <> (); private BlockingQueue usedConnectinoList = new LinkedBlockingQueue <> (); private int initialPoolSize = 5;

@Autowired
@Qualifier("dataSource")
private DataSource dataSource;

public void initConnectionPool() {
    logger.info("ConnectionPool initialization started.");
    if(activeConnectinoQueue.isEmpty() && usedConnectinoList.isEmpty()) {
        for (int i=0; i<initialPoolSize; i++) {
            createConnections();
        }
    }
    logger.info("ConnectionPool initialization completed. ConnectionPool size : {}", activeConnectinoQueue.size());
}

private void createConnections() {
    try {
        Connection connection = dataSource.getConnection();
        activeConnectinoQueue.add(connection);
    }catch (SQLException e) {
        logger.error("Error in getting connection from pool : ", e);
    }
}

public Connection getConnection() {
    if(activeConnectinoQueue.isEmpty()) {
        initConnectionPool();
    }
    Connection connection =  activeConnectinoQueue.remove();

    try {
        if(connection.isClosed()) {
            connection = dataSource.getConnection();
        }
    }catch (SQLException e) {
        logger.error("Error while getting connection from pool : ", e);
    }

    usedConnectinoList.add(connection);
    return connection;
}


public void releaseConnection(Connection connection) {
    if(connection != null) {
        usedConnectinoList.remove(connection);
        activeConnectinoQueue.add(connection);
    }
}

public void setInitialPoolSize(int initialPoolSize) {
    if(!(initialPoolSize < 0 || initialPoolSize > MAX_POOL_SIZE_LIMIT)) {
        this.initialPoolSize = initialPoolSize;
    }
}

public int getInitialPoolSize() {
    return initialPoolSize;
}

public int getConnectionPoolSize() {
    return activeConnectinoQueue.size() + usedConnectinoList.size();
}

public void setDataSource(AbstractDataSource dataSource) {
    this.dataSource = dataSource;
}

public void closeConnectionPool() {

    logger.info("Closing connectionPool started.");
    close(usedConnectinoList);
    close(activeConnectinoQueue);
    logger.info("ConnectionPool Closed.");
}

private void close(BlockingQueue<Connection> connectinosQueue) {
    for (int i=0; i<connectinosQueue.size(); i++) {
        Connection connection = connectinosQueue.remove();
        if(connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                logger.error("Error in initializing connection pool : ", e);
            }
        }
    }
}

}

jetzt müssen wir ein Fabrikobjekt anbringen, um die Sicherheit zu gewährleisten.

public enum ConnectionFactory {
CONNECTION;

private ConnectionPool connectionPool;
public void setConnectionPool(ConnectionPool connectionPool) {
    this.connectionPool = connectionPool;
}

public Connection getConnection() {
    return connectionPool.getConnection();
}

public void closeConnection() {
    connectionPool.closeConnectionPool();
}

public void releaseConnection(Connection connection) {
    connectionPool.releaseConnection(connection);
}

public int getConnectionPoolSize() {
    return connectionPool.getConnectionPoolSize();
}

@Component
public static class ConnectionBuilder {
    @Autowired
    private ConnectionPool connectionPool;

    public void setConnectionPool(ConnectionPool connectionPool) {
        this.connectionPool = connectionPool;
    }
    @PostConstruct
    public void postConstruct() {
        for (ConnectionFactory cfactory : EnumSet.allOf(ConnectionFactory.class)) {
            cfactory.setConnectionPool(connectionPool);
        }
    }
}

}