使用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. TableView 键盘弹起冲突

    1.TableView 上cell 带有 TextField,如果 是Plain 形式的TableView ,并且设置SectionHeader的 取消粘滞效果 会导致键盘弹起,页面不能正常 上移 问 ...

  2. Navicat连接Mysql11.1.13出现1251错误

    打开Navicat软件,单击左上角[连接]按钮,选择mysql,弹出新建连接,输入相关信息,单击[连接测试],报1251的错误,如下图所示: 根因分析: mysql8 之前的版本中加密规则是mysql ...

  3. Delphi 监视数据的值

  4. 009(1)-saltstack之salt-ssh的使用及配置管理LAMP状态的实现

    1 salt-ssh的使用 1. 安装salt-ssh[root@slave1 .ssh]# yum install -y salt-ssh 2. 配置salt-ssh # Sample salt-s ...

  5. 02-springmvc分布式项目dataService项目配置

    spring总文件 文件名:applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> ...

  6. 去掉或修改lightinthebox网址与标题中Wholesale关键词

    includes\languages\english.php define('SEO_COMMON_KEYWORDS','Wholesale'); 将里面的Wholesale换成你想显示的词即可.

  7. C#线程中LOCK的意义

    学习心得,为的是让新人能理解,高手直接绕~ lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区.如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放. 引用一句 ...

  8. 高性能mysql 第7章 mysql高级特性之分区表

    分区表: 分区表是一个独立的逻辑表,底层通过多个物理表实现. mysql实现分区表的方式是对底层表的封装.这意味着没有全局索引,索引是建立在底层的每个表上的(跟ORACLE不一样). 用到分区表的几种 ...

  9. 【CF1181D】Irrigation

    题目大意:给定 M 个城市,每年会选出一个城市举办比赛,现给出前 N 年城市举办比赛的情况.在接下来的年份中,每年会在举办比赛次数最小的城市举办比赛,如果有很多城市举办次数均为最小值,则在编号最小的城 ...

  10. 浮点数的存储、类型转换知识点(面宝P34)

    以float a=1.0f为例: (int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1: (int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换),即读a的内存时 ...