使用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的更多相关文章

  1. Python MySQLdb模块连接操作mysql数据库实例_python

    mysql是一个优秀的开源数据库,它现在的应用非常的广泛,因此很有必要简单的介绍一下用python操作mysql数据库的方法.python操作数据库需要安装一个第三方的模块,在http://mysql ...

  2. python使用MySQLdb模块连接MySQL

    1.安装驱动 目前有两个MySQL的驱动,我们可以选择其中一个进行安装: MySQL-python:是封装了MySQL C驱动的Python驱动:mysql-connector-python:是MyS ...

  3. python MySQLdb用法,python中cursor操作数据库(转)

    数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB. 在TESTDB数据库中您已经创建了表 EMPLOYEE EMPLOYEE表字段为 FIRST_NAME, LAST_N ...

  4. 【Python】如何基于Python写一个TCP反向连接后门

    首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...

  5. python MySQLdb连接mysql失败(转载)

    最近了解了一下django,数据库选用了mysql, 在连接数据库的过程中,遇到一点小问题,在这里记录一下,希望能够对遇到同样的问题的朋友有所帮助,少走一些弯路.关于django,想在这里也额外说一句 ...

  6. 一个jdbc connection连接对应一个事务

    Spring保证在methodB方法中所有的调用都获得到一个相同的连接.在调用methodB时,没有一个存在的事务,所以获得一个新的连接,开启了一个新的事务. Spring保证在methodB方法中所 ...

  7. Python MySQLdb 模块使用方法

    import MySQLdb 2.和数据库建立连接 conn=MySQLdb.connect(host="localhost",user="root",pass ...

  8. python mysqldb 教程

    MySQL Python 教程 (1)下面是在Python中使用MySql数据库的教程,涵盖了Python对MySql的基础操作,主要采用了MySQLdb模块,下面的代码都是基于Ubuntu Linu ...

  9. Python MySQLdb 学习总结(转)

    转自http://www.cnblogs.com/coser/archive/2012/01/12/2320741.html 感谢@糖拌咸鱼 任何应用都离不开数据,所以在学习python的时候,当然也 ...

随机推荐

  1. 七,ingress及ingress cluster

    目录 Service 类型 namespace 名称空间 Ingress Controller Ingress Ingress-nginx 进行测试 创建对应的后端Pod和Service 创建 Ing ...

  2. Linux内核管理子系统和进程管理子系统

    内核管理子系统职能:1.管理虚拟地址与物理地址的映射 2.物理内存的分配 程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体. 进程:是一个执行中的程序,它是动态的实体 进程四要素: ...

  3. 模拟赛小结:2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

    比赛链接:传送门 两个半小时的时候横扫了铜.银区的所有题,签到成功混进金区.奈何后面没能开出新的题. 最后一个小时的时候xk灵机一动想出了D题的做法,讨论了一波感觉可行,赶紧去敲.结束前2分钟终于过了 ...

  4. 关于tp5.0中对象数组转换普通数组使用助手函数collection而不是toArray

    tp5.0新版的模型查询返回默认对象,系统默认增加了toArray方法,许多开发者在all或select尝试使用toArray来转换为数组,在此希望开发者能理解对象的概念,尝试使用对象进行数据的使用, ...

  5. Django学习系列18:使用迁移创建生产数据库

    Django生成一个很有帮助的错误信息,大意是说没有正确设置数据库. 你可能会有疑惑,为什么在单元测试一切都运行ok,这是因为Django为单元测试创建了专用的测试数据库——这是Django中Test ...

  6. 三大方面,分析 to B和 to C产品的区别

    作为互联网从业者,我们经常听到to B(或2B)和to C(或2C)两个概念.to B即面向企业客户,to C即面向普通用户.只要是互联网人基本都懂知道这两个概念,但如果别人再问“to B和to C产 ...

  7. 【每日一包0001】is-sorted

    github地址:https://github.com/ABCDdouyae... is-sorted 用于判断数组是否被排序了 文档地址:https://www.npmjs.com/package/ ...

  8. Hangfire:任务定时调度

    hangfire 资源: GitHub:https://github.com/HangfireIO/Hangfire http://hangfire.io/ http://docs.hangfire. ...

  9. 关于 vue中 export default 和 new Vue({})

    对于刚开始学习vue的人(像我),一般都不会清楚的知道两者之间该怎么区分,甚至觉得两者是一样的. 那么,经过我的查证,发现两者之间是没有任何联系的. export default ES6 Module ...

  10. Spring、SpringMVC和Springboot的区别

    spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc. spring mvc 是只是spring 处理web层请求的一个模 ...