多线程程序访问数据时出错。
Exception in thread Thread-2:
ProgrammingError: (2014, "Commands out of sync; you can't run this command now")
Exception in thread Thread-3:
ProgrammingError: execute() first
答案 0 :(得分:13)
根据PEP 249,数据访问模块具有模块级常量threadsafety
:
整数常量表示接口的线程安全级别 支持。可能的值有:
0线程可能不共享模块。
1线程可以共享模块,但不能共享连接 2线程可以共享模块和连接。
3个线程可以共享模块,连接和 光标。在上面的上下文中共享意味着两个线程可以使用资源 不使用互斥信号量来包装它来实现资源 锁定。请注意,您无法始终创建外部资源线程 通过使用互斥锁管理访问来保护安全:资源可能依赖于全局 变量或其他无法控制的外部资源。
根据MySQLdb User's Guide,该模块支持1级。
MySQL协议无法使用相同的处理多个线程 立刻连接。一些早期版本的MySQLdb使用了锁定 实现2的线程安全。虽然这不是非常难 完成使用标准的Cursor类(使用 mysql_store_result()),由SSCursor复杂化(使用 了mysql_use_result();对于后者,您必须确保所有行都有 在执行另一个查询之前已被读取。它是进一步的 由于交易开始,因此增加了交易 当游标执行查询时,但在COMMIT或ROLLBACK结束时结束 由Connection对象执行。两个线程根本无法共享一个 事务正在进行中的连接,除此之外 能够在查询执行期间共享它。这个过分了 将代码复杂化到不值得的地步。
这样做的一般结果是:不要分享之间的联系 线程。这真的不值得你的努力或我的努力,最后, 可能会损害性能,因为MySQL服务器单独运行 每个连接的线程。你当然可以做像缓存这样的事情 池中的连接,并将这些连接提供给a处的一个线程 时间。如果让两个线程同时使用连接,那么 MySQL客户端库可能会崩溃并死掉。你去过 警告。
答案 1 :(得分:2)
此处有关于错误的详细信息:http://dev.mysql.com/doc/refman/5.0/en/commands-out-of-sync.html。
Mysqldb的手册建议:
不要在线程之间共享连接。这真的不值得你或我的努力,最终,可能会损害性能,因为MySQL服务器为每个连接运行一个单独的线程。您当然可以执行缓存池中的连接等操作,并一次将这些连接提供给一个线程。如果让两个线程同时使用连接,那么MySQL客户端库可能会崩溃并死掉。你被警告了。
对于线程应用程序,请尝试使用连接池。这可以使用Pool模块
完成在MySQLdb manual上查看更多信息搜索关键字threadsafety,
答案 2 :(得分:0)
感谢你的一些信息,我只能猜测。
您可能无需锁定即可从多个线程访问数据库。那很糟糕。
您应该在访问数据库时锁定threading.Lock()
或threading.RLock()
。这可以防止多个线程干扰其他线程的操作。