python MySQLdb 一个连接connection多个cursor
使用MySQLdb时,如果创建一个连接connection,多个线程同时使用,会不会有问题?
在下文中,我们将模拟这种场景,看是否会出现问题。
1.示例
1.1 正常的情况
创建一个连接,两个线程同时使用这个连接,生成游标cursor,进行查询,并输出结果。
程序启动后,让线程1睡眠1s,保证让线程2线执行。
import MySQLdb
import threading
import time
def get_connection():
host = "127.0.0.1"
port = 3306
user = "root"
passwd = "Aa123456"
conn = MySQLdb.connect(host=host, port=port, user=user,passwd=passwd, connect_timeout=2, charset="utf8")
return conn
def thread1_runtime(conn, sql):
time.sleep(1)
cursor = conn.cursor()
cursor.execute(sql)
ret = cursor.fetchone()
thread_name = threading.current_thread().name
print("thread name:%s, ret:%s" %(thread_name, ret))
def thread2_runtime(conn, sql):
cursor = conn.cursor()
cursor.execute(sql)
ret = cursor.fetchone()
thread_name = threading.current_thread().name
print("thread name:%s, ret:%s" %(thread_name, ret))
if __name__ == "__main__":
thread1_sql = "select 1"
thread2_sql = "select 2"
conn = get_connection()
thread1 = threading.Thread(target=thread1_runtime, name="thread 001", args=(conn, thread1_sql))
thread2 = threading.Thread(target=thread2_runtime, name="thread 002", args=(conn, thread2_sql))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("...main exit....")
从结果可以看到,一切正常。
output:
thread name:thread 002, ret:(2,)
thread name:thread 001, ret:(1,)
...main exit....
1.2 异常的情况
以下例子中,程序启动后,线程1和线程2使用同一连接创建新的游标cursor,执行查询。
接着,线程1睡眠1秒,线程2睡眠2秒。
最后各自打印查询结果。
import MySQLdb
import threading
import time
def get_connection():
host = "127.0.0.1"
port = 3306
user = "root"
passwd = "Aa123456"
conn = MySQLdb.connect(host=host, port=port, user=user,passwd=passwd, connect_timeout=2, charset="utf8")
return conn
def thread1_runtime(conn, sql):
cursor = conn.cursor()
cursor.execute(sql)
time.sleep(1)
ret = cursor.fetchone()
thread_name = threading.current_thread().name
print("thread name:%s, ret:%s" %(thread_name, ret))
def thread2_runtime(conn, sql):
cursor = conn.cursor()
cursor.execute(sql)
time.sleep(2)
ret = cursor.fetchone()
thread_name = threading.current_thread().name
print("thread name:%s, ret:%s" %(thread_name, ret))
if __name__ == "__main__":
thread1_sql = "select 1"
thread2_sql = "select 2"
conn = get_connection()
thread1 = threading.Thread(target=thread1_runtime, name="thread 001", args=(conn, thread1_sql))
thread2 = threading.Thread(target=thread2_runtime, name="thread 002", args=(conn, thread2_sql))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("...main exit....")
output:
Exception in thread thread 002:
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "one_conn_mutiple_cursor.py", line 28, in thread2_runtime
cursor.execute(sql)
File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 198, in execute
res = self._query(query)
File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 304, in _query
db.query(q)
File "/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 217, in query
_mysql.connection.query(self, query)
MySQLdb._exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")
thread name:thread 001, ret:(1,)
...main exit....
从打印结果可以看到,线程1可以正常打印结果,但线程2报错了。
线程1睡眠先结束,去获取查询结果,可以打印。
线程2睡眠后结束,再去获取查询结果,已经无法获取结果了。
2.总结
从上面例子中,我们可以得出结论:
一个连接connection同一个时间点只能有一个cursor,执行sql,并获取结果。
所以,不要在多个线程中同时使用一个连接connection,否则会出现不可预料的结果。
python MySQLdb 一个连接connection多个cursor的更多相关文章
- Python MySQLdb模块连接操作mysql数据库实例_python
mysql是一个优秀的开源数据库,它现在的应用非常的广泛,因此很有必要简单的介绍一下用python操作mysql数据库的方法.python操作数据库需要安装一个第三方的模块,在http://mysql ...
- python使用MySQLdb模块连接MySQL
1.安装驱动 目前有两个MySQL的驱动,我们可以选择其中一个进行安装: MySQL-python:是封装了MySQL C驱动的Python驱动:mysql-connector-python:是MyS ...
- python MySQLdb用法,python中cursor操作数据库(转)
数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB. 在TESTDB数据库中您已经创建了表 EMPLOYEE EMPLOYEE表字段为 FIRST_NAME, LAST_N ...
- 【Python】如何基于Python写一个TCP反向连接后门
首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...
- python MySQLdb连接mysql失败(转载)
最近了解了一下django,数据库选用了mysql, 在连接数据库的过程中,遇到一点小问题,在这里记录一下,希望能够对遇到同样的问题的朋友有所帮助,少走一些弯路.关于django,想在这里也额外说一句 ...
- 一个jdbc connection连接对应一个事务
Spring保证在methodB方法中所有的调用都获得到一个相同的连接.在调用methodB时,没有一个存在的事务,所以获得一个新的连接,开启了一个新的事务. Spring保证在methodB方法中所 ...
- Python MySQLdb 模块使用方法
import MySQLdb 2.和数据库建立连接 conn=MySQLdb.connect(host="localhost",user="root",pass ...
- python mysqldb 教程
MySQL Python 教程 (1)下面是在Python中使用MySql数据库的教程,涵盖了Python对MySql的基础操作,主要采用了MySQLdb模块,下面的代码都是基于Ubuntu Linu ...
- Python MySQLdb 学习总结(转)
转自http://www.cnblogs.com/coser/archive/2012/01/12/2320741.html 感谢@糖拌咸鱼 任何应用都离不开数据,所以在学习python的时候,当然也 ...
随机推荐
- Spring Boot【快速入门】简单案例
Spring Boot[快速入门] Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point ...
- 免费安装正版Xshell6+Xftp6
先进入链接获取最新的下载地址 下载地址 填写一下姓名+邮箱,勾选需要哪个就行了 它会发给你指定邮箱一个地址,点击即可下载 安装就不用说了...
- Windows Electron初探
最近闲来无事,玩玩electron. 1.安装nodejs 下载地址:http://nodejs.cn/download/,下载64位.安装完成后,打开C:\Program Files\nodejs\ ...
- 多线程 - 线程通信 suspend-resume wait-notify park-unpark 伪唤醒
线程通信(如 线程执行先后顺序,获取某个线程执行的结果等)有多种方式: 文件共享 线程1 --写入--> 文件 < --读取-- 线程2 网络共享 变量共享 线程1 --写入--> ...
- html 不刷新切换当前页面内容
一个小功能,做个笔记: 操作流程是:导航产品有三个下拉子菜单,点击食品跳转,同时跳转出来的子页面中,选中食品这个当前项. 切换 食品 厨具 家电 三个选项卡在刷新页面的时候仍然停留在当前选中 ...
- 团队作业-Beta冲刺(周五)
一. 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 这个作业要求在哪里 https://edu.c ...
- Python代码风格的良好养成
Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下,不同程序员编写的 Python 代码可以保持最大程度的相似风格.这样就易于阅读, ...
- [HDU 3521] [最小割] Being a Hero
题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...
- libusb读写
https://blog.csdn.net/u012247418/article/details/83684980 https://github.com/crazybaoli/libusb-test ...
- ffmpeg函数04__v_register_output_format()
注册复用器,编码器等的函数av_register_all() 注册编解码器avcodec_register_all() 注册复用器的函数是av_register_output_format(). 注册 ...