You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python2.7中使用pool.apply_async无法向MySQL表插入值的问题

聊聊并行填充MySQL表的dbWriter函数优化

嘿,看了你这段用来并行填充MySQL表的dbWriter函数,我发现几个关键细节需要调整,尤其是在并行场景下,这些点直接影响程序的稳定性和效率:

1. 别每次调用都新建数据库连接!

你现在的写法是每次执行dbWriter都重新创建数据库连接,要是用多线程/多进程并行跑,很快就会把MySQL的连接数占满,触发Too many connections错误。

建议换成连接池的方式,提前初始化好连接池,每次用的时候从池里拿连接,用完归还。比如用DBUtils的PooledDB实现:

import os
import MySQLdb
from DBUtils.PooledDB import PooledDB

# 全局初始化连接池,整个程序只执行一次
MYSQL_CNF = os.path.abspath('.') + '/mysql.cnf'
db_pool = PooledDB(
    creator=MySQLdb,
    read_default_file=MYSQL_CNF,
    db='dedupe',
    charset='utf8',
    maxconnections=10,  # 数值根据你的并行任务数调整
    blocking=True  # 无可用连接时等待,而非直接报错
)

def dbWriter(sql, rows):
    conn = None
    cursor = None
    try:
        # 从连接池获取连接
        conn = db_pool.connection()
        cursor = conn.cursor()
        cursor.executemany(sql, rows)
        conn.commit()
    except Exception as e:
        # 出错必须回滚,避免数据不一致
        if conn:
            conn.rollback()
        # 可根据需求添加日志记录或自定义异常处理
        raise e
    finally:
        # 无论成功失败,都要释放资源
        if cursor:
            cursor.close()
        if conn:
            conn.close()  # 此处是归还连接到池,而非真正关闭

2. 必须加上异常处理!

原函数完全没有异常捕获,要是插入时遇到主键冲突、数据格式错误这类问题,程序直接崩溃不说,还会导致部分数据插入成功、部分失败,造成数据混乱。上面的代码加了try-except-finally块,确保出错时回滚事务,且一定会释放游标和连接。

3. 并行场景的额外提醒

  • 若使用多进程,注意连接池不能在主进程初始化后直接传给子进程,建议每个子进程单独初始化连接池,或使用进程安全的连接池实现。
  • 批量插入的rows别太大,否则会触发MySQL的max_allowed_packet限制,太小又没效率,一般每次插1000-5000条比较合适(具体看单条数据的大小)。
  • 确保你的表使用支持事务的引擎(比如InnoDB),如果是MyISAM,commit毫无意义,且并行插入会有锁的问题,效率极低。

4. 别忘了收尾原函数!

你原代码里cursor.clos...没写完,不管用不用连接池,游标和连接都一定要手动关闭,不然会造成连接泄漏,时间长了照样会占满连接数。

内容的提问来源于stack exchange,提问作者mersa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:54:24