多线程爬虫中实现线程安全的MySQL连接池

多线程爬虫中实现线程安全的MySQL连接池

在日常开发中,数据库操作频繁建立/关闭连接会带来性能损耗,尤其在多线程场景中更容易出现连接复用、阻塞等问题。因此,本文介绍如何使用 Python 封装一个 线程安全的 MySQL 连接池,并通过 threading 模拟多线程高并发操作数据库。


一、项目背景

  • 目标: 封装一个通用的、可复用的、线程安全的 MySQL 连接池类
  • 实现: 使用 DBUtilsPooledDB 实现底层连接池逻辑,支持最大连接数、最小缓存连接数等参数
  • 特点:
    • 多线程安全
    • 自动释放连接
    • 封装常用的 CRUD 操作
    • 内置异常处理与日志输出

二、依赖准备

pip install pymysql DBUtils

三、连接池封装代码(ConnectionPool)

# CoreUtils/Sql.py
import pymysql
import logging
import traceback
from DBUtils.PooledDB import PooledDBclass ConnectionPool:"""多线程同步连接池"""def __init__(self, host, database, user=None, password=None,port=3306, charset="utf8mb4", max_connections=10,min_cached=2, max_cached=5, blocking=True):"""初始化连接池"""self._pool = PooledDB(creator=pymysql,maxconnections=max_connections,mincached=min_cached,maxcached=max_cached,blocking=blocking,host=host,port=port,user=user,password=password,database=database,charset=charset,use_unicode=True,cursorclass=pymysql.cursors.DictCursor,autocommit=True)def _get_conn(self):return self._pool.connection()def query(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.fetchall()finally:cursor.close()conn.close()def get(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.fetchone()finally:cursor.close()conn.close()def execute(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:return cursor.execute(sql, params)except Exception as e:traceback.print_exc()logging.error(f"SQL执行错误: {e}\nSQL: {sql}\nParams: {params}")raisefinally:cursor.close()conn.close()def insert(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.lastrowidexcept Exception as e:logging.error(f"插入出错: {e}\nSQL: {sql}\nParams: {params}")raisefinally:cursor.close()conn.close()def table_has(self, table_name, field, value):sql = f"SELECT {field} FROM {table_name} WHERE {field}=%s LIMIT 1"return self.get(sql, value)def table_insert(self, table_name, item: dict):fields = list(item.keys())values = list(item.values())placeholders = ','.join(['%s'] * len(fields))field_list = ','.join(fields)sql = f"INSERT INTO {table_name} ({field_list}) VALUES ({placeholders})"try:return self.execute(sql, values)except pymysql.MySQLError as e:if e.args[0] == 1062:logging.warning("重复插入被跳过")else:logging.error("插入数据出错: %s\n数据: %s", e, item)raisedef table_update(self, table_name, updates: dict, field_where: str, value_where):set_clause = ', '.join([f"{k}=%s" for k in updates])values = list(updates.values()) + [value_where]sql = f"UPDATE {table_name} SET {set_clause} WHERE {field_where}=%s"self.execute(sql, values)

四、多线程测试代码

以下代码通过 10 个线程并发对数据库进行增删改查,测试连接池的稳定性与日志输出的整洁性。

import threading
import logging
from CoreUtils.Sql import ConnectionPool# 日志格式配置
logging.basicConfig(level=logging.INFO,format='[%(asctime)s][%(levelname)s][%(threadName)s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S'
)# 初始化连接池
pool = ConnectionPool(host='localhost',database='test_db',user='root',password='your_password',port=3306
)def test_multithread():def thread_task(i):name = f"User-{i}"age = 20 + itry:pool.insert("INSERT INTO test_table (name, age) VALUES (%s, %s)", (name, age))logging.info(f"插入成功: {name}")data = pool.get("SELECT * FROM test_table WHERE name=%s", (name,))logging.info(f"查询结果: {data}")pool.execute("UPDATE test_table SET age = age + 1 WHERE name = %s", (name,))logging.info("年龄更新完成")updated = pool.get("SELECT * FROM test_table WHERE name=%s", (name,))logging.info(f"更新后数据: {updated}")pool.execute("DELETE FROM test_table WHERE name=%s", (name,))logging.info("删除完成")pool.table_insert("test_table", {"name": f"{name}_new", "age": age})logging.info("table_insert 成功")exists = pool.table_has("test_table", "name", f"{name}_new")logging.info(f"table_has 检查: {exists is not None}")pool.table_update("test_table", {"age": 99}, "name", f"{name}_new")logging.info("table_update 完成")except Exception as e:logging.exception("线程异常")threads = []for i in range(10):t = threading.Thread(target=thread_task, args=(i,), name=f"Thread-{i}")threads.append(t)t.start()for t in threads:t.join()logging.info("多线程测试完成")if __name__ == "__main__":test_multithread()

五、准备测试数据表

CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) UNIQUE NOT NULL,age INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

六、运行结果示意

运行后,你将看到类似如下整齐的日志输出:

在这里插入图片描述

你可以根据实际项目需要将日志输出到文件中(通过 filename='xxx.log' 配置 logging.basicConfig())。


七、总结

本文介绍了一个线程安全的 MySQL 连接池封装方式,并通过多线程场景验证其并发稳定性。在高并发读写、日志整洁输出、连接复用等方面表现良好,适用于中小型 Python 爬虫项目中的数据库访问层封装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML:常用标签(元素)汇总

文章目录 一、标签分类1、块标签与行标签 二、排版标签三、文本标签1、常用2、不常用 四、图片标签五、超链接1、跳转页面2、跳转文件或下载文件3、跳转到锚点4、唤起本地应用 六、列表七、表格八、表单九、框架十、HTML实体十一、全局属性十二、meta元信息 一、标签分类 1、块…

20250430在ubuntu14.04.6系统上完成编译NanoPi NEO开发板的FriendlyCore系统【严重不推荐,属于没苦硬吃】

【开始编译SDK之前需要更新源】 rootrootubuntu:~/friendlywrt-h3$ sudo apt update 【这两个目录你在ubuntu14.04.6系统上貌似git clone异常了】 Y:\friendlywrt-h3\out\wireguard Y:\friendlywrt-h3\kernel\exfat-nofuse 【需要单线程编译文件系统,原因不明】 Y:…

【AI论文】CipherBank:通过密码学挑战探索LLM推理能力的边界

摘要:大型语言模型(LLMs)已经展现出非凡的能力,尤其是最近在推理方面的进步,如o1和o3,推动了人工智能的发展。尽管在数学和编码方面取得了令人印象深刻的成就,但在需要密码学专业知识的领域&…

艺术与科技的双向奔赴——高一鑫荣获加州联合表彰

2025年4月20日,在由M.A.D公司协办的“智艺相融,共赴价值巅峰”(Academic and Artistic Fusion Tribute to the Summit of Value)主题发布会上,音乐教育与科技融合领域的代表人物高一鑫,因其在数字音乐教育与中美文化交流方面的杰出贡献,荣获了圣盖博市议员Jorge Herrera和尔湾市…

【深度学习的灵魂】图片布局生成模型LayoutPrompt(1)

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀《深度学习理论直觉三十讲》_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目…

Compose笔记(二十)--TextField

这一节主要了解一下Compose的TextField,TextField 是一个用于接收用户文本输入的 UI 组件,允许用户通过键盘输入、编辑或删除文本。简单用法总结如下: API value:当前输入的文本内容。 onValueChange 含义:当用户输入文本时触发的回调函数,参…

在Linux虚拟机下使用vscode,#include无法跳转问题

总结:需要通过Linux指令来添加编译器和压缩文件,解压,这样获得的编译器会具有可执行权限类似于 -rwxr-xr-x 1 user user 12345 Apr 26 14:22 myscript.sh 如果你直接从window中拖入文件到Linux文件下,你需要自己来再度开启可编译…

ArcGIS+GPT:多领域地理分析与决策新方案

技术点目录 AI大模型应用ArcGIS工作流程及功能prompt的使用技巧AI助力工作流程AI助力数据读取AI助力数据编辑与处理AI助力空间分析AI助力遥感分析AI助力二次开发AI助力科研绘图ArcGISAI综合应用了解更多 ——————————————————————————————————…

基础术语说明

车间:工厂内集中进行加工或装配的独立空间,配备设备、工具及人员,是生产活动的核心载体。 比如装配车间、总装车间、油漆车间等 生产线:以流水作业形式将原材料转化为成品的设备与人员的组合系统,强调连续性和效率。…

Splunk 使用Role 实现数据隔离

很多人知道 Splunk 有很多自带的Role, 今天我就要说说定制化的Role: 1: 在创建新role 的界面: 2: 在如下的界面,可以定制allow index name: 3: 创建好新Role 后,在SAML 添加新的group 的时候,就可以看到Role 给某个group: 4: 这样一个特定组的人来申请Splunk 权限,就可…

利用李雅普诺夫稳定性理论设计模型参考自适应系统(2.0)

上一篇介绍了利用李雅普诺夫稳定性理论设计模型参考自适应系统,通过在被控对象前面添加一个可调增益,然后利用李雅普诺夫稳定性理论设计增益的自适应率,使得被控对象输出与参考模型输出一致。本文将介绍在系统结构中引入前馈和反馈的结构&…

前端封装WebSocket工具n

Web API 提供的 WebSocket 类,封装一个 Socket 类 // socket.js import modal from /plugins/modal const baseURL import.meta.env.VITE_APP_BASE_WS; const EventTypes [open, close, message, error, reconnect]; const DEFAULT_CHECK_TIME 55 * 1000; // 心…

TCP和UDP传输层协议

TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是两种常见的传输层协议,它们在网络通信中发挥着不同的作用。二者在连接建立、可靠性、传输效率等方面存在显著差异,适用于不同的应用场…

空域伦理与AI自主边界的系统建构

在AI无人系统逐步参与城市空域治理的过程中,系统的“自主性”已不再仅是技术指标,而是直接影响合规性、安全性与社会接受度的伦理边界议题。AI决策系统是否拥有“强干预能力”?行为触发责任应归属何方?算法可否调优至“自我纠偏”…

在原生代码(非webpack)里使用iview的注意事项

最近公司在做一个项目,使用的框架是iview,使用过程中同事遇到一些问题,这些问题对于有些同学来说根本就不是问题,但总会有同学需要,为了帮助不太会用的同学快速找到问题,做了如下整理: 下载vue,iview.min.j…

java代码混淆

生成jar的时候混淆 目前最常用的Proguard,网上有很多介绍的文章,这种安全性较低 对已经生成的jar进行加密 加密库:https://github.com/li571312729/classfinal 测试对jar进行加密 加密后如果正常调用的话会失败 加密后jar反编译查看不到代码 使用密码才能调用机…

【Linux】第十三章 访问Linux文件系统

目录 1. 存储设备是什么?怎么理解分区和格式化? 2. 文件系统是什么? 3. 挂载是什么?挂载点是什么? 4. 怎么理解块设备? 5. 在SATA附加存储中,第一磁盘上的第一个分区和第二磁盘的第二个分区…

MCP 服务器搭建【stdio 类型】实现上市公司年报查询总结,配合 Cherry Studio使用简单

代码解释 这段 Python 代码的主要功能是搭建一个基于 FastAPI 的 MCP 服务器,用于处理通过股票代码查询上市公司年报的请求,实现服务器向客户端的实时消息推送。以下是对代码各部分的详细解释: 完整代码+使用 Cherry Studio 调用 MCP 服务器的方法,放在文章最后了 1. 导…

第六节:软件安装

理论知识 软件安装的方式:在 Linux 系统中,常见的软件安装方式有源码安装、在线安装、deb 包安装、RPM 包安装、使用 Snap 管理软件包等。不同的安装方式适用于不同的软件和场景。源码安装:源码安装是指从软件的源代码开始,进行编…

ubantu部署yolov5(第四集:模型加速)

参考链接: GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite TFLite,ONNX,CoreML,TensorRT Export -Ultralytics YOLO Docs 使用Neural Magic 的 DeepSparse 部署YOLOv5 -Ultralytics YOLO 文档 sparseml/inte…