pooledDB

引入连接池

  • 多个人同时调用时,创建一定数量的连接(抽象为一个池子),如果连接池有空闲连接,就给多个人其中一个人,如果没空,就有人需要等待
  • 连接数设置一般为(核心数*2)+有效磁盘数
  • 当不使用django自带的orm时,一般使用连接池连接数据库

两种模式(persistentDB和poolDB)

  • persistentDB

  • 为每一个进来的现场创建一个连接,线程调用close也不会关闭,只是把连接重新放到连接池,供自己线程再次使用,当线程终止时连接自动关闭。(但限制了创建的上线,达到上线就必须等待线程关闭后再创建新的)

  • 创建方式:自己独有一份,通过threading.local来保存线程数据,独有连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     import pymysql
    pymysql.install_as_MySQLdb()
    from dbutils.pooled_db import PooledDB
    from dbutils.persistent_db import PersistentDB


    Pool1 = PersistentDB(
    creator=pymysql, # 使用连接mysql的模块客户端
    maxusage=None, # 创建的一个连接最多使用多少次
    setsession=[], # 执行一些命令修改session variables,在此session链接中可用的配置文件,也是sql命令
    ping=0, # 为0永远不会ping,客户端在这里拿连接时,通过ping保证连接可用,为0就不能保证了,如果为7就是always只要拿链接就检查
    # 如果为2 when a cursor is created, 4 when a query is executed 1.default whenever it is requested 一般4或者7
    closeable=False, # 如果为False,conn.close()实际上会被忽略,如果为True就真的关闭了,会出问题,之后你的线程就没有连接了,也获取不到
    threadlocal=None, # if thread_local is None, use threading.local,也可以自定义local,比如之前的
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123456',
    charset='utf8',
    db='test'
    )

  • pooledDB

  • 创建好一批连接池,供所有线程共享使用,总数就那么多个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Pool2 = PooledDB(
    creator=pymysql, # 使用连接mysql的模块客户端
    maxconnections=6, # 连接池允许的最大连接数,o和None不限制连接数
    mincached=2, # 初始化时链接池中最少创建的空闲的连接,0表示不创建
    maxcached=5, # 链接池中最多闲置的连接数,0和None表示不限制
    maxshared=3, # 连接池中最多共享的连接数,0和None表示全部共享,无用:因为pymysql和MYSQLdb等模块的threadsafety为1
    # 线程安全让为每个线程创建的连接不能共享给别的线程使用
    blocking=True, # 连接池没有可用连接后是否阻塞等待。True等待!False不等待直接报错
    maxusage=None, # 一个连接可以被使用多少次,None表示无限制
    setsession=[],
    ping=0,
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123456',
    charset='utf8',
    db='test'
    )
    def func():
    conn = Pool1.connection(shareable=False)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from bb')
    results = cursor.fetchall()
    print(results)


    func()

3.3 简单使用pooledDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class MySQL(object):
def __init__(self, username, password, hostname, db_name, charset='utf8mb4'):
self.username = username
self.password = password
self.db_name = db_name
self.hostname = hostname
self.log = log
self.pool = PooledDB(
creator=MySQLdb,
mincached=0,
maxcached=6,
maxshared=3,
blocking=True,
ping=0,
maxusage=None,
host=self.hostname,
user=self.username,
passwd=self.password,
db=self.db_name,
port=3306,
charset=charset
)

def manipulate_db(self, sql, pairs=True):
db = None
cursor = None
try:
db = self.pool.connection()
if pairs:
cursor = db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
else:
cursor = db.cursor()
cursor.execute(sql)
if 'select' in sql or 'SELECT' in sql:
return cursor.fetchall()
else:
# select does not need commit(), only update/insert/delete need it
db.commit()
except Exception as e:
self.log('[{}] meet error'.format(sql))
self.log(e)
if 'select' not in sql and 'SELECT' not in sql:
# select does not need rollback
db.rollback()
return ()
finally:
if cursor:
cursor.close()
if db:
db.close()

return True
分享到