python多线程ThreadPoolExecutor池操作mysql连接池报AttributeError: 'NoneType' object has no attribute 'read'
时间: 2023-08-02 10:07:39 浏览: 275
这个错误通常是由于多个线程同时使用同一个 MySQL 连接引起的。在使用 `ThreadPoolExecutor` 线程池时,每个线程都是从线程池中获取的,因此需要确保每个线程都有自己独立的连接。
你可以尝试以下解决方案:
1. 使用 `ThreadPoolExecutor` 的 `submit` 方法结合 `with` 语句,确保每个线程在执行完数据库操作后都能正确地关闭和释放连接。
```python
import concurrent.futures
import pymysql
# 创建连接池
conn_pool = pymysql.pool.Pool(host='your_host', user='your_user', password='your_password', database='your_database')
def worker():
# 获取连接
with conn_pool.get_conn() as conn:
# 使用连接进行数据库操作
# 创建线程池
with concurrent.futures.ThreadPoolExecutor() as executor:
# 提交任务给线程池执行
executor.submit(worker)
```
2. 如果你想手动管理连接的生命周期,可以使用 `ThreadPoolExecutor` 的 `submit` 方法结合 `threading.local()` 创建线程局部变量来管理每个线程的连接。
```python
import concurrent.futures
import threading
import pymysql
# 创建连接池
conn_pool = pymysql.pool.Pool(host='your_host', user='your_user', password='your_password', database='your_database')
# 创建线程局部变量
local = threading.local()
def worker():
# 获取连接
conn = get_connection()
try:
# 使用连接进行数据库操作
finally:
# 最后记得释放连接
release_connection(conn)
def get_connection():
# 检查当前线程是否已经有连接,如果有则直接返回
if hasattr(local, 'conn'):
return local.conn
# 创建新的连接
conn = conn_pool.get_conn()
# 保存连接到线程局部变量
local.conn = conn
return conn
def release_connection(conn):
# 释放连接到连接池中
conn_pool.release(conn)
# 从线程局部变量中删除连接
del local.conn
# 创建线程池
with concurrent.futures.ThreadPoolExecutor() as executor:
# 提交任务给线程池执行
executor.submit(worker)
```
以上是两种常见的解决方案,你可以根据自己的需求选择其中一种。同时,也建议使用连接池库来方便地管理和获取数据库连接,例如 `pymysqlpool` 或 `DBUtils`。
阅读全文