python数据库连接工具DBUtils

DBUtils是一个允许在多线程python应用和数据库之间安全及高效连接的python模块套件。

模块

DBUtils套件包含两个模块子集,一个适用于兼容DB-API 2接口的模块,一个适用于PyGreSQL的模块。

  • Universal DB-API 2 variant

    该子集下的模块依赖关系如图:

  • Classic PyGreSQL variant

    该子集下的模块依赖关系如图:

SimplePooledDB

DBUtils.SimplePooledDB是池化数据库连接中非常基础的一种实现。相较于PooledDB,它并不那么复杂,且缺少failover机制。SimplePooledDB应视为一种概念演示,不要直接在生产环境使用。

SteadyDB

DBUtils.SteadyDB基于兼容DB-API 2接口的数据库模块创建的普通连接,实现了"加强"连接。具体指当数据库连接关闭、丢失或使用频率超出限制时,将自动重新获取连接。

典型的应用场景如下:在某个维持了某些数据库连接的程序运行时重启了数据库,或在某个防火墙隔离的网络中访问远程数据库时重启了防火墙。

PersistentDB

DBUtils.PersistentDB实现了稳定,线程仿射(thread-affine),持久化的数据库连接。下图显式了使用PersistentDB进行连接时涉及的连接层:

某个线程第一次开启一个数据库连接时,该连接将用于此特定线程。即使在线程中关闭连接,连接也会保持打开状态,以便同一个线程的下一次连接请求直接使用。线程结束时该连接会自动关闭。

简而言之:PersistentDB会回收数据库连接从而在整体上增加多线程应用的数据库访问性能,它确保线程之间永远不会共享连接。

因此即使底层的DB-API模块不是connection级别的线程安全,PersistentDB也可以完美实现线程安全,避免在其他线程更改数据库会话或执行跨多个SQL指令的事务时出现问题。


要使用PersistentDB模块,首先传递以下参数创建PersistentDB实例:

  • creator:兼容DB-API 2的数据库模块或返回DB-API 2连接的任意函数
  • maxusage:单个连接的最大重用次数(0或None表示无重用次数限制),达到该限制后自动关闭并重新打开连接
  • setsession:设置连接会话的sql指令列表,比如["set wait_timeout = 100", ...]
  • failures:异常类或异常类元组。在默认的(OperationalError, InternalError)不能处理连接failover机制时使用
  • ping:如果ping()方法可用,该值表示何时使用ping()方法检查连接(0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always, and all other bit combinations of these values)
  • closeable:如果设置为True,将允许手动close()连接,默认为False,忽略关闭连接的操作,只在线程终止时自动关闭
  • threadlocal:表示thread-local数据的类。设置值为threading.local可能获取连接的速度更快,但不一定适用于所有情况(例如,mod_wsgi会清空requests之间的threading.local数据)
  • 传递给creator参数值创建connection对象的参数,如host, database等
import pymysql
from DBUtils.PersistentDB import PersistentDB persist = PersistentDB(creator=pymysql, user="root", passwd="123456", db="test")
# conn的使用和常规DB-API 2接口类似
conn = persist.connection()

NOTE:需要在连接上调用begin()方法明确开启事务。这可以确保a.只在事务完成时才重新打开连接b.连接被同一个线程重用时回滚。

PooledDB

DBUtils.PooledDB实现了稳定、线程安全的缓存连接池。下图显式了使用PooledDB进行连接时涉及的连接层:

使用正整数的maxshared参数和connection级别的线程安全的creator参数创建连接池时,连接池中的连接默认是线程间共享的。但仍可以请求非线程共享的专用数据库连接。

除了共享连接池外,还可以创建至少mincached个,至多maxcached个连接的空闲连接池,在共享连接池未满(不太理解)或线程请求专用数据库连接时使用。当某个线程关闭不再共享的连接时,该连接将回收到空闲连接池以便再次使用。

如果底层的DB-API 2模块非线程安全,将使用线程锁确保PooledDB连接是线程安全的。但对于线程专用的连接,要小心更改数据库会话或执行跨多个SQL指令的事务带来的不良影响。


要使用PoolDB模块,首先传递以下参数创建PoolDB实例:

  • creator:同PersistentDB
  • mincached:连接池中空闲连接的初始数量(0表示不创建初始空闲连接)
  • maxcached:连接池中允许的最大空闲连接数(0或None表示无限制)
  • maxshared:允许的最大共享连接数(0或None表示所有连接都是专用的),When this maximum number is reached, connections are shared if they have been requested as shareable
  • maxconnections:允许的最大连接数(0或None表示无限制)
  • blocking:查过最大值是否阻塞。True表示将阻塞直到释放新的连接,默认False表示抛出异常
  • maxusage:同PersistentDB
  • setsession:同PersistentDB
  • reset:返回连接池时应该怎样重置连接(False或None将只回滚明确调用了begin()开启的事务,默认值为True,出于安全考虑总是会回滚)
  • failures:同PersistentDB
  • ping:同PersistentDB
  • 传递给creator参数值创建connection对象的参数,如host, database等
import pymysql
from DBUtils.PooledDB import PooledDB pool = PooledDB(creator=pymysql, 5, user="root", passwd="123456", db="test")
# conn的使用和常规DB-API 2接口类似
conn = pool.connection()

对于线程共享的连接池,可以用以下方式获取线程专用连接:

conn = pool.connection(shareable=False)
# 或者
conn = pool.dedicated_connection()

对于不再使用的连接,调用close()方法回收到连接池。

在多线程环境中,不要写以下代码,这会导致连接过早释放并被其他线程重用,如果连接非线程安全可能导致程序出现严重错误:

pool.connection().cursor().execute(...)

NOTE:需要在连接上调用begin()方法明确开启事务。这可以确保a.只在事务完成时才重新打开连接b.连接在返回连接池之前执行回滚c.连接不会被其他线程共享

如何选择

PooledDB和PersistentDB都通过回收数据库连接,且即使数据库连接中断也能保持稳定性的方式从而达到提升数据库访问性能的目的。在现实场景中应该如何选择呢?对于保持常量线程数且频繁使用数据库的应用,使用PersistentDB;对于频繁开启、结束线程的应用,使用PooledDB。

其他

如果程序中使用了ORM框架,如SQLObjectSQLAlchemy,不需要使用DBUtils,因为这些框架自身维护了连接池。

数据库线程安全级别:

比如pymysql就是可以共享模块但不能共享连接,查看方式pymysql.threadsafety

https://segmentfault.com/a/1190000017952033

DBUtil内部实现过程解读的更多相关文章

  1. 【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程

    [前提] 想要实现使用某种语言,比如Python,C#等,去实现模拟登陆网站的话,首先要做的事情就是使用某种工具,去分析本身使用浏览器去登陆网页的时候,其内部的执行过程,内部逻辑. 此登陆的逻辑过程, ...

  2. CLRMonitor - 跟踪CLR内部执行过程工具

    CLRMonitor v1.0.1511.13 点击此处下载 软件介绍:这款软件主要用于跟踪CLR内部执行过程,定位当前程序执行的命名空间以及方法名等信息.可以迅速找到被跟踪程序的当前执行方法名.本软 ...

  3. 【Spring-web】RestTemplate源码学习——梳理内部实现过程

    2016-12-28 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6228198.html  提示:使用手机浏览时请注意,图多费流量. 本篇 ...

  4. ORACLE之SQL语句内部解析过程【weber出品】

    一.客户端通过监听连接到数据库,数据库开启一个server process进程来接收客户端传过来的sql. 1.这条sql语句从来都没有被执行过.(硬解析) 2.这条sql语句被执行过.(软解析) 二 ...

  5. STM32启动过程解读与跟踪验证

    经过查阅各种官方文献和对代码进行单步跟踪,详细地叙述了STM32加电启动的具体过程.对于关键性的语句都指明了出处.下面将学习成果分享给大家,由于笔者知识有限,不当之处敬请指出. 为了更好的说明问题,先 ...

  6. HttpApplication 对象的创建过程及HttpModule过滤器的内部实现过程

    最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅. 先看下HttpApplication 对象的创建过程 从IHttpHandler applicationInst ...

  7. 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

    先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...

  8. Struts2内部执行过程

    首先是Struts2的流程图. 一.当有一个请求的时候.执行以下流程. 1 客户端初始化一个指向Servlet容器的请求: 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做Act ...

  9. mysql系列二、mysql内部执行过程

    向MySQL发送一个请求的时候,MySQL到底做了什么 客户端发送一条查询给服务器. 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器端进行SQL解析.预 ...

随机推荐

  1. nginx日志配置笔记:if条件

    1.特定条件写日志: 参照: https://stackoverflow.com/questions/19011719/how-to-write-only-logs-with-200-status h ...

  2. 运输层6——TCP可靠传输的实现

    目录 1. 以字节为单位的滑动窗口 2. 超时重传时间的选择 写在前面:本文章是针对<计算机网络第七版>的学习笔记 运输层1--运输层协议概述 运输层2--用户数据报协议UDP 运输层3- ...

  3. 基于Java+Selenium的WebUI自动化测试框架(四)-----设置监听类

    基于上一篇的内容,这里我们开始写监听类Listener.我这里写监听类的思路是,继承TestListenerAdapter这个类,然后对其中的方法进行重写.网上也有很多资料,建议先学习一下,然后写出来 ...

  4. linux网络编程之posix条件变量

    今天来学习posix的最后一个相关知识----条件变量,言归正传. 下面用一个图来进一步描述条件变量的作用: 为什么呢? 这实际上可以解决生产者与消费者问题,而且对于缓冲区是无界的是一种比较理解的解决 ...

  5. re模块及其用法

    一.re模块下的常用方法 首先在使用re模块之前,需要引入re模块 import re 1.与查找相关的: 1.findall 返回列表,找到所有的匹配项 ret = re.findall(" ...

  6. POI进行导出时候发现有不可读取的内容

    通过后台查询数据,然后使用poi进行导出时候,excel进行打开会出现下面的异常: 但是在WPS中就没有问题, 如果点击否,则不会显示任何内容,点击是,就会弹出来 查看修改记录为: 刚开始也进行了很多 ...

  7. Mac OS下安装MongoDB以及配置方法总结【笔记】

    首先打开命令框,输入: brew install mongodb 安装完成后  启动.停止.重启如下 brew services start mongodb brew services stop mo ...

  8. webpack中配置babel时遇到的问题

    1.Error: Cannot find module '@babel/core' babel-loader@8 requires Babel 7.x (the package '@babel/cor ...

  9. MLP多层感知机

    @author:wepon @blog:http://blog.csdn.net/u012162613/article/details/43221829 转载:http://blog.csdn.net ...

  10. Hdu 4312-Meeting point-2——哈夫曼距离与切比雪夫距离

    题意 从 $n$ 个点中选择一点,使得其他点到其的切比雪夫距离最小($0 < n \leq 1e5$). 分析 定理:$(x_1, y_1)$ 与 $(x_2, y_2)$ 的曼哈顿距离等于 $ ...