TL; DR:我已经为我发现的一个bug提供了一个补丁,我得到了0个反馈.我想知道这是不是一个错误.这不是咆哮.请阅读此内容,如果您可能受其影响,请检查修复程序.
几周前我发现并报告了这个MySQLdb错误(编辑:6周前),发送补丁,发布在几个ORM的论坛上,邮寄了MySQLdb作者,邮寄了一些人谈论处理死锁,邮寄ORM作者和我我还在等待任何反馈.
这个bug给我带来了很多的悲伤,我可以在反馈中找到的唯一解释是,无论是在python中使用mysql还是没有人使用"SELECT ... FOR UPDATE",或者这不是一个bug.
基本上问题是当使用MySQLdb游标发出"SELECT ... FOR UPDATE"时,不会引发死锁和"锁定等待超时"异常.相反,该语句以静默方式失败并返回一个空的结果集,任何应用程序都会将其解释为没有匹配的行.
我测试了SVN版本,但它仍然受到影响.在Ubuntu Intrepid,Jaunty和Debian Lenny的默认安装上进行测试,这些也会受到影响.easy_install(1.2.3c1)安装的当前版本受到影响.
这也会影响SQLAlchemy和SQLObject,并且可能任何使用MySQLdb游标的ORM也会受到影响.
此脚本可以重现将触发错误的死锁(只需更改get_conn中的用户/传递,它将创建必要的表):
import time
import threading
import traceback
import logging
import MySQLdb
def get_conn():
return MySQLdb.connect(host='localhost', db='TESTS',
user='tito', passwd='testing123')
class DeadlockTestThread(threading.Thread):
def __init__(self, order):
super(DeadlockTestThread, self).__init__()
self.first_select_done = threading.Event()
self.do_the_second_one = threading.Event()
self.order = order
def log(self, msg):
logging.info('%s: %s' % (self.getName(), msg))
def run(self):
db = get_conn()
c = db.cursor()
c.execute('BEGIN;')
query = 'SELECT * FROM locktest%i FOR UPDATE;'
try:
try:
c.execute(query % self.order[0])
self.first_select_done.set() …Run Code Online (Sandbox Code Playgroud)