Python Multiprocessing Pool传字典参数时SQL语句未执行问题
问题根因
- 多进程资源隔离:主进程初始化的数据库连接、游标
cur无法被子进程共享,子进程调用的cur属于未初始化的无效对象,由于apply_async默认不会抛出子进程异常,所以你看不到错误提示,误以为代码运行正常 - 事务未提交:绝大多数关系型数据库默认开启手动事务,执行
UPDATE类写操作后,必须调用连接的commit()方法,变更才会真正写入数据库生效 - 执行状态无校验:你没有接收异步任务的返回结果,无法确认任务实际是执行成功还是异常退出
修复后代码示例
from multiprocessing import Pool # 以下为示例,换成你实际使用的数据库驱动,比如pymysql、cx_Oracle等 import pymysql dict_of_queries={'D': 'UPDATE D SET ROW2=100', 'E':'UPDATE E SET ROW2=100'} def fn(value): try: # 每个子进程单独创建数据库连接,禁止跨进程共享连接资源 conn = pymysql.connect( host="你的数据库主机地址", user="数据库用户名", password="数据库密码", database="操作的库名" ) cur = conn.cursor() cur.execute(value) # 提交事务,也可以在创建连接时传入autocommit=True实现自动提交 conn.commit() cur.close() conn.close() return f"执行成功:{value}" except Exception as e: return f"执行失败:{value},错误信息:{str(e)}" if __name__ == "__main__": p = Pool(processes=2) result_pool = [] for _, value in dict_of_queries.items(): res = p.apply_async(fn, args=(value, )) result_pool.append(res) p.close() p.join() # 打印所有任务执行结果,确认执行状态 for item in result_pool: print(item.get())
关键注意事项
- 数据库连接是进程不安全的资源,绝对不能在主进程创建连接后传给子进程使用,必须每个子进程单独初始化自己的连接
- 所有写操作执行完成后必须提交事务,否则变更只会保存在会话缓存中,不会真正写入数据库
- 异步任务提交后建议接收返回结果,调用
get()方法可以主动抛出子进程中的异常,方便快速定位问题
内容的提问来源于stack exchange,提问作者Rajesh S
相关产品推荐
相关产品推荐

