摘要:是一個允許在多線程應(yīng)用和數(shù)據(jù)庫之間安全及高效連接的模塊套件。實現(xiàn)了穩(wěn)定,線程仿射,持久化的數(shù)據(jù)庫連接。線程結(jié)束時該連接會自動關(guān)閉。但仍可以請求非線程共享的專用數(shù)據(jù)庫連接。
DBUtils是一個允許在多線程python應(yīng)用和數(shù)據(jù)庫之間安全及高效連接的python模塊套件。
模塊DBUtils套件包含兩個模塊子集,一個適用于兼容DB-API 2接口的模塊,一個適用于PyGreSQL的模塊。
Universal DB-API 2 variant
該子集下的模塊依賴關(guān)系如圖:
Classic PyGreSQL variant
該子集下的模塊依賴關(guān)系如圖:
DBUtils.SimplePooledDB是池化數(shù)據(jù)庫連接中非?;A(chǔ)的一種實現(xiàn)。相較于PooledDB,它并不那么復(fù)雜,且缺少failover機制。SimplePooledDB應(yīng)視為一種概念演示,不要直接在生產(chǎn)環(huán)境使用。
SteadyDBDBUtils.SteadyDB基于兼容DB-API 2接口的數(shù)據(jù)庫模塊創(chuàng)建的普通連接,實現(xiàn)了"加強"連接。具體指當數(shù)據(jù)庫連接關(guān)閉、丟失或使用頻率超出限制時,將自動重新獲取連接。
典型的應(yīng)用場景如下:在某個維持了某些數(shù)據(jù)庫連接的程序運行時重啟了數(shù)據(jù)庫,或在某個防火墻隔離的網(wǎng)絡(luò)中訪問遠程數(shù)據(jù)庫時重啟了防火墻。
PersistentDBDBUtils.PersistentDB實現(xiàn)了穩(wěn)定,線程仿射(thread-affine),持久化的數(shù)據(jù)庫連接。下圖顯式了使用PersistentDB進行連接時涉及的連接層:
某個線程第一次開啟一個數(shù)據(jù)庫連接時,該連接將用于此特定線程。即使在線程中關(guān)閉連接,連接也會保持打開狀態(tài),以便同一個線程的下一次連接請求直接使用。線程結(jié)束時該連接會自動關(guān)閉。
簡而言之:PersistentDB會回收數(shù)據(jù)庫連接從而在整體上增加多線程應(yīng)用的數(shù)據(jù)庫訪問性能,它確保線程之間永遠不會共享連接。
因此即使底層的DB-API模塊不是connection級別的線程安全,PersistentDB也可以完美實現(xiàn)線程安全,避免在其他線程更改數(shù)據(jù)庫會話或執(zhí)行跨多個SQL指令的事務(wù)時出現(xiàn)問題。
要使用PersistentDB模塊,首先傳遞以下參數(shù)創(chuàng)建PersistentDB實例:
creator:兼容DB-API 2的數(shù)據(jù)庫模塊或返回DB-API 2連接的任意函數(shù)
maxusage:單個連接的最大重用次數(shù)(0或None表示無重用次數(shù)限制),達到該限制后自動關(guān)閉并重新打開連接
setsession:設(shè)置連接會話的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:如果設(shè)置為True,將允許手動close()連接,默認為False,忽略關(guān)閉連接的操作,只在線程終止時自動關(guān)閉
threadlocal:表示thread-local數(shù)據(jù)的類。設(shè)置值為threading.local可能獲取連接的速度更快,但不一定適用于所有情況(例如,mod_wsgi會清空requests之間的threading.local數(shù)據(jù))
傳遞給creator參數(shù)值創(chuàng)建connection對象的參數(shù),如host, database等
import pymysql from DBUtils.PersistentDB import PersistentDB persist = PersistentDB(creator=pymysql, user="root", passwd="123456", db="test") # conn的使用和常規(guī)DB-API 2接口類似 conn = persist.connection()
NOTE:需要在連接上調(diào)用begin()方法明確開啟事務(wù)。這可以確保a.只在事務(wù)完成時才重新打開連接b.連接被同一個線程重用時回滾。
PooledDBDBUtils.PooledDB實現(xiàn)了穩(wěn)定、線程安全的緩存連接池。下圖顯式了使用PooledDB進行連接時涉及的連接層:
使用正整數(shù)的maxshared參數(shù)和connection級別的線程安全的creator參數(shù)創(chuàng)建連接池時,連接池中的連接默認是線程間共享的。但仍可以請求非線程共享的專用數(shù)據(jù)庫連接。
除了共享連接池外,還可以創(chuàng)建至少mincached個,至多maxcached個連接的空閑連接池,在共享連接池未滿(不太理解)或線程請求專用數(shù)據(jù)庫連接時使用。當某個線程關(guān)閉不再共享的連接時,該連接將回收到空閑連接池以便再次使用。
如果底層的DB-API 2模塊非線程安全,將使用線程鎖確保PooledDB連接是線程安全的。但對于線程專用的連接,要小心更改數(shù)據(jù)庫會話或執(zhí)行跨多個SQL指令的事務(wù)帶來的不良影響。
要使用PoolDB模塊,首先傳遞以下參數(shù)創(chuàng)建PoolDB實例:
creator:同PersistentDB
mincached:連接池中空閑連接的初始數(shù)量(0表示不創(chuàng)建初始空閑連接)
maxcached:連接池中允許的最大空閑連接數(shù)(0或None表示無限制)
maxshared:允許的最大共享連接數(shù)(0或None表示所有連接都是專用的),When this maximum number is reached, connections are shared if they have been requested as shareable
maxconnections:允許的最大連接數(shù)(0或None表示無限制)
blocking:查過最大值是否阻塞。True表示將阻塞直到釋放新的連接,默認False表示拋出異常
maxusage:同PersistentDB
setsession:同PersistentDB
reset:返回連接池時應(yīng)該怎樣重置連接(False或None將只回滾明確調(diào)用了begin()開啟的事務(wù),默認值為True,出于安全考慮總是會回滾)
failures:同PersistentDB
ping:同PersistentDB
傳遞給creator參數(shù)值創(chuàng)建connection對象的參數(shù),如host, database等
import pymysql from DBUtils.PooledDB import PooledDB pool = PooledDB(creator=pymysql, 5, user="root", passwd="123456", db="test") # conn的使用和常規(guī)DB-API 2接口類似 conn = pool.connection()
對于線程共享的連接池,可以用以下方式獲取線程專用連接:
conn = pool.connection(shareable=False) # 或者 conn = pool.dedicated_connection()
對于不再使用的連接,調(diào)用close()方法回收到連接池。
在多線程環(huán)境中,不要寫以下代碼,這會導(dǎo)致連接過早釋放并被其他線程重用,如果連接非線程安全可能導(dǎo)致程序出現(xiàn)嚴重錯誤:
pool.connection().cursor().execute(...)
NOTE:需要在連接上調(diào)用begin()方法明確開啟事務(wù)。這可以確保a.只在事務(wù)完成時才重新打開連接b.連接在返回連接池之前執(zhí)行回滾c.連接不會被其他線程共享
如何選擇PooledDB和PersistentDB都通過回收數(shù)據(jù)庫連接,且即使數(shù)據(jù)庫連接中斷也能保持穩(wěn)定性的方式從而達到提升數(shù)據(jù)庫訪問性能的目的。在現(xiàn)實場景中應(yīng)該如何選擇呢?對于保持常量線程數(shù)且頻繁使用數(shù)據(jù)庫的應(yīng)用,使用PersistentDB;對于頻繁開啟、結(jié)束線程的應(yīng)用,使用PooledDB。
其他如果程序中使用了ORM框架,如SQLObject或SQLAlchemy,不需要使用DBUtils,因為這些框架自身維護了連接池。
數(shù)據(jù)庫線程安全級別:
比如pymysql就是可以共享模塊但不能共享連接,查看方式pymysql.threadsafety
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/17881.html
摘要:是一個允許在多線程應(yīng)用和數(shù)據(jù)庫之間安全及高效連接的模塊套件。實現(xiàn)了穩(wěn)定,線程仿射,持久化的數(shù)據(jù)庫連接。線程結(jié)束時該連接會自動關(guān)閉。但仍可以請求非線程共享的專用數(shù)據(jù)庫連接。 DBUtils是一個允許在多線程python應(yīng)用和數(shù)據(jù)庫之間安全及高效連接的python模塊套件。 模塊 DBUtils套件包含兩個模塊子集,一個適用于兼容DB-API 2接口的模塊,一個適用于PyGreSQL的模塊...
摘要:不用自己來創(chuàng)建,而是通過池來獲取對象使用完后,調(diào)用的方法也不會真的關(guān)閉,而是把歸還給池連接池技術(shù)可以完成對象的再次利用接口為數(shù)據(jù)庫連接池提供了公共的接口各個廠商需要讓自己的連接池實現(xiàn)這個接口。 01DButils工具類的介紹個三個核心類 * A: DButils工具類的介紹個三個核心類 * a: 概述 * DBUtils是java編程中的數(shù)據(jù)庫操作實用工具,小巧...
摘要:不用自己來創(chuàng)建,而是通過池來獲取對象使用完后,調(diào)用的方法也不會真的關(guān)閉,而是把歸還給池連接池技術(shù)可以完成對象的再次利用接口為數(shù)據(jù)庫連接池提供了公共的接口各個廠商需要讓自己的連接池實現(xiàn)這個接口。 1.DButils工具類的介紹個三個核心類 A: 概述 DBUtils是java編程中的數(shù)據(jù)庫操作實用工具,小巧簡單實用。 DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少...
閱讀 3052·2023-04-26 00:32
閱讀 537·2019-08-30 15:52
閱讀 2139·2019-08-30 15:52
閱讀 3385·2019-08-30 15:44
閱讀 3311·2019-08-30 14:09
閱讀 1441·2019-08-29 15:15
閱讀 3427·2019-08-28 18:12
閱讀 1110·2019-08-26 13:55