连接池的基本原理? 以及使用连接池的好处?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了连接池的基本原理? 以及使用连接池的好处?相关的知识,希望对你有一定的参考价值。
请详细谈论一下,数据库连接池的原理,和使用数据库连接池 的好处??
最好能够附带一个自定义的数据库连接池的例子!!!
不胜感激!!!!!1
import java.sql.*;
import java.util.*;
public class DBConnpool
private int inUse = 0;
private Vector<Connection> connections = new Vector<Connection>();
private String poolname = "dbconnpool";
private String dbid = "jdbc:mysql://localhost:3306/teasystem";
private String drivername = "com.mysql.jdbc.Driver";
private String username = "root";
private String password = "123";
private int maxconn = 5000;
public DBConnpool()
public void setdbid(String dbid)
this.dbid = dbid;
public void setusername(String username)
this.username = username;
public void setpassword(String password)
this.password = password;
public void setmaxconn(int maxconn)
this.maxconn = maxconn;
public String getdbid()
return dbid;
public String getusername()
return username;
public String getpassword()
return password;
public int getmaxconn()
return maxconn;
//将连接返还给连接池
public synchronized void reConnection(Connection conn)
Connection con = conn;
connections.addElement(con);
inUse--;
//从连接池获取一个连接
public synchronized Connection getConnection()
Connection con = null;
if(connections.size()>0)
con = (Connection)connections.elementAt(0);
connections.removeElementAt(0);
try
if(con.isClosed())
con = getConnection();
catch(Exception e)
e.printStackTrace();
else if(maxconn == 0||inUse<maxconn)
con = newConnection();
if(con != null)
inUse++;
return con;
private Connection newConnection()
Connection con = null;
try
Class.forName(drivername);
con = DriverManager.getConnection(dbid,username,password);
catch(Exception e)
e.printStackTrace();
return null;
return con;
public synchronized void closeConn()
Enumeration allConnections = connections.elements();
while(allConnections.hasMoreElements())
Connection con = (Connection)allConnections.nextElement();
try
con.close();
catch(SQLException e)
e.printStackTrace();
使用连接池,把暂时不使用的链接放入连接池,到需要使用的时候,从连接池中取出链接使用本回答被提问者采纳
python 里的 redis 连接池的原理
python设置redis连接池的好处:
通常情况下,需要连接redis时,会创建一个连接,基于这个连接进行redis操作,操作完成后去释放,
正常情况下,这是没有问题的,但是并发量较高的情况下,频繁的连接创建和释放对性能会有较高的影响,于是连接池发挥作用。
连接池的原理:‘预先创建多个连接,当进行redis操作时,直接获取已经创建好的连接进行操作。完成后,不会释放这个连接,
而是让其返回连接池,用于后续redis操作!这样避免连续创建和释放,从而提高了性能!
import redis pool = redis.ConnectionPool(host=‘127.0.0.1‘,port=6379,password=‘12345‘) r = redis.Redis(connection_pool=pool) r.set(‘name‘,‘michael‘) print(r.get(‘name‘))
pool = redis.ConnectionPool(host=‘127.0.0.1‘,port=6379,password=‘12345‘) 直接点击connectionPool,进去查看源码: def __init__(self, connection_class=Connection, max_connections=None, **connection_kwargs): max_connections = max_connections or 2 ** 31 if not isinstance(max_connections, (int, long)) or max_connections < 0: raise ValueError(‘"max_connections" must be a positive integer‘) self.connection_class = connection_class self.connection_kwargs = connection_kwargs self.max_connections = max_connections self.reset() 发现里面只是 设置最大的连接数,连接参数,连接的类,在实例化的时候,并没有做真实的redis连接。
r = redis.Redis(connection_pool=pool) 点击Redis,查看内部的源码: 在Redis实例化的时候,做了什么; def __init__(self, ...connection_pool=None...): if not connection_pool: ... connection_pool = ConnectionPool(**kwargs) self.connection_pool = connection_pool 以上只保留了部分代码: 可见:使用Redis即使不创建连接池,也会自己创建 到这,发现还没有实际的redis真实连接
r.set(‘name‘,‘michael‘) 点击set,查看内部源码: def set(self, name, value, ex=None, px=None, nx=False, xx=False): ... return self.execute_command(‘SET‘, *pieces) 在此处发现了方法,execute_command,点击进去查看 def execute_command(self, *args, **options): "Execute a command and return a parsed response" pool = self.connection_pool command_name = args[0] conn = self.connection or pool.get_connection(command_name, **options) try: conn.send_command(*args) return self.parse_response(conn, command_name, **options) except (ConnectionError, TimeoutError) as e: conn.disconnect() if not (conn.retry_on_timeout and isinstance(e, TimeoutError)): raise conn.send_command(*args) return self.parse_response(conn, command_name, **options) finally: if not self.connection: pool.release(conn) 找到了conn = self.connection or pool.get_connection(command_name, **options) 因为self.connection初始值为False,所以此处调用了方法 get_connection 点击查看get_connection, def get_connection(self, command_name, *keys, **options): "Get a connection from the pool" self._checkpid() try: connection = self._available_connections.pop() except IndexError: connection = self.make_connection() self._in_use_connections.add(connection) 。。。。。。 except: # noqa: E722 self.release(connection) raise return connection 如果有有用的连接,获取可用的连接,没有,自己创建一个 make_connection ,点击查看make_connection def make_connection(self): "Create a new connection" if self._created_connections >= self.max_connections: raise ConnectionError("Too many connections") self._created_connections += 1 return self.connection_class(**self.connection_kwargs) 终于,在此处创建了连接!!! 在ConnectionPool的实例中, 有两个list, 依次是_available_connections, _in_use_connections, 分别表示可用的连接集合和正在使用的连接集合, 在上面的get_connection中, 我们可以看到获取连接的过程是: 从可用连接集合尝试获取连接, 如果获取不到, 重新创建连接 将获取到的连接添加到正在使用的连接集合 上面是往_in_use_connections里添加连接的, 这种连接表示正在使用中, 那是什么时候将正在使用的连接放回到可用连接列表中的呢 这个还是在execute_command里, 我们可以看到在执行redis操作时, 在finally部分, 会执行一下 pool.release(connection) 连接池对象调用release方法, 将连接从_in_use_connections 放回 _available_connections, 这样后续的连接获取就能再次使用这个连接了 release 方法如下 def release(self, connection): "Releases the connection back to the pool" self._checkpid() if connection.pid != self.pid: return self._in_use_connections.remove(connection) self._available_connections.append(connection) 至此, 我们把连接池的管理流程走了一遍, ConnectionPool通过管理可用连接列表(_available_connections) 和 正在使用的连接列表从而实现连接池管理!
以上是关于连接池的基本原理? 以及使用连接池的好处?的主要内容,如果未能解决你的问题,请参考以下文章