如何在MySQLdb中启用MySQL客户端自动重连?
我发现了用PHP来解决这个问题的方法:
my_bool reconnect = 1;
mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
但是在使用MySQLdb(python-mysql)时没有成功。
有没有人能给我一点提示?谢谢。
9 个回答
如果你在使用Ubuntu Linux,之前有一个更新被加到了python-mysql这个包里,这个更新让你可以设置MYSQL_OPT_RECONNECT这个选项(具体可以查看这里)。不过我没有尝试过这个功能。
可惜的是,这个更新后来被撤回了,因为它和自动连接及事务处理有冲突(详细情况可以查看这里)。
那页面上的评论提到:
1.2.2-7 版本在2008年6月19日的intrepid-release中发布
python-mysqldb (1.2.2-7) 不稳定;紧急程度=低
[ Sandro Tosi ]
* debian/control
- 描述中的列表项行前加了两个空格,以避免在网页上重新格式化(关闭:#480341)
[ Bernd Zeimetz ]
* debian/patches/02_reconnect.dpatch:
- 撤回这个更新:
Storm中的评论解释了这个问题:
# Here is another sad story about bad transactional behavior. MySQL
# offers a feature to automatically reconnect dropped connections.
# What sounds like a dream, is actually a nightmare for anyone who
# is dealing with transactions. When a reconnection happens, the
# currently running transaction is transparently rolled back, and
# everything that was being done is lost, without notice. Not only
# that, but the connection may be put back in AUTOCOMMIT mode, even
# when that's not the default MySQLdb behavior. The MySQL developers
# quickly understood that this is a terrible idea, and removed the
# behavior in MySQL 5.0.3. Unfortunately, Debian and Ubuntu still
# have a patch right now which *reenables* that behavior by default
# even past version 5.0.3.
我在使用提议的解决方案时遇到了问题,因为它没有捕捉到异常。我不太明白为什么会这样。
我用 ping(True)
这个语句解决了问题,我觉得这样更简洁:
import MySQLdb
con=MySQLdb.Connect()
con.ping(True)
cur=con.cursor()
这个方法是从这里找到的: http://www.neotitans.com/resources/python/mysql-python-connection-error-2006.html
我通过创建一个函数来解决这个问题,这个函数封装了cursor.execute()
这个方法,因为正是这个方法引发了MySQLdb.OperationalError
这个错误。上面的另一个例子暗示是conn.cursor()
这个方法引发了这个错误。
import MySQLdb
class DB:
conn = None
def connect(self):
self.conn = MySQLdb.connect()
def query(self, sql):
try:
cursor = self.conn.cursor()
cursor.execute(sql)
except (AttributeError, MySQLdb.OperationalError):
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql)
return cursor
db = DB()
sql = "SELECT * FROM foo"
cur = db.query(sql)
# wait a long time for the Mysql connection to timeout
cur = db.query(sql)
# still works