Я занимался разработкой программного обеспечения с витой, где мне приходилось использовать постоянное соединение с базой данных MySQL. я столкнулся с этой проблемой, много копался в искаженной документации и отправил несколько вопросов, но не смог найти правильного решения. Есть логический параметр, который вы можете передать, когда создаете экземпляр класса adbapi.connectionPool; однако, это никогда не казалось работающим, и я продолжал получать ошибку независимо от. Тем не менее, я предполагаю, что логическое значение пересоединения представляет собой уничтожение объекта соединения, когда происходит отключение SQL.
adbapi.ConnectionPool("MySQLdb", cp_reconnect=True, host="", user="", passwd="", db="")
Я не проверял это, но я опубликую некоторые результаты, когда я делаю или, если кто-то еще, пожалуйста, поделитесь.
Когда я разрабатывал сценарий, я использовал Twisted 8.2.0 (я не касался Twisted некоторое время), и тогда у фреймворка не было такого явного метода keep alive, поэтому я разработал расширение ping / keepalive, использующее управляемую событиями парадигму. витая сборка в сочетании с прямым методом модуля pSQL () модуля MySQLdb (см. комментарий к коду).
Как я печатал этот ответ; Тем не менее, я просмотрел текущую искаженную документацию, но все еще не смог найти явный метод или параметр keep-alive. Я предполагаю, что у Twisted нет библиотек / классов подключения к базе данных. Он использует методы, доступные для python, и обеспечивает косвенный уровень взаимодействия с этими модулями; с некоторой выдержкой для прямых обращений к используемой библиотеке базы данных. Это достигается с помощью метода adbapi.runWithConnection.
вот модуль, который я написал под twisted 8.2.0 и python 2.6; Вы можете установить интервалы между пингами. Сценарий выполняет следующие действия: каждые 20 минут он проверяет связь с базой данных, а в случае сбоя он пытается подключиться к нему каждые 60 секунд. Я должен предупредить, что скрипт НЕ обрабатывает внезапное / потерянное соединение; что вы можете обрабатывать через addErrback всякий раз, когда вы запускаете запрос через витую, по крайней мере, вот как я это сделал. Я заметил, что всякий раз, когда соединение с базой данных прерывается, вы можете узнать, есть ли оно, когда вы выполняете запрос, и событие вызывает ошибку, а затем в этот момент вы имеете дело с этим. По сути, если я не выполняю запрос в течение 10 минут, и моя база данных отключает меня, мое приложение не будет отвечать в режиме реального времени. приложение поймет, что соединение было разорвано, когда запустит следующий запрос; таким образом, база данных могла отключить нас через 1 минуту после первого запроса, 5, 9 и т. д.
Я предполагаю, что этот вид восходит к первоначальной идее, которую я изложил, Twisted использует собственные библиотеки Python или сторонние библиотеки для подключения к базе данных, и поэтому некоторые вещи обрабатываются немного по-другому.
from twisted.enterprise import adbapi
from twisted.internet import reactor, defer, task
class sqlClass:
def __init__(self, db_pointer):
self.dbpool=db_pointer
self.dbping = task.LoopingCall(self.dbping)
self.dbping.start(1200) #20 minutes = 1200 seconds; i found out that if MySQL socket is idled for 20 minutes or longer, MySQL itself disconnects the session for security reasons; i do believe you can change that in the configuration of the database server itself but it may not be recommended.
self.reconnect=False
print "database ping initiated"
def dbping(self):
def ping(conn):
conn.ping() #what happens here is that twisted allows us to access methods from the MySQLdb module that python posesses; i chose to use the native command instead of sending null commands to the database.
pingdb=self.dbpool.runWithConnection(ping)
pingdb.addCallback(self.dbactive)
pingdb.addErrback(self.dbout)
print "pinging database"
def dbactive(self, data):
if data==None and self.reconnect==True:
self.dbping.stop()
self.reconnect=False
self.dbping.start(1200) #20 minutes = 1200 seconds
print "Reconnected to database!"
elif data==None:
print "database is active"
def dbout(self, deferr):
#print deferr
if self.reconnect==False:
self.dbreconnect()
elif self.reconnect==True:
print "Unable to reconnect to database"
print "unable to ping MySQL database!"
def dbreconnect(self, *data):
self.dbping.stop()
self.reconnect=True
#self.dbping = task.LoopingCall(self.dbping)
self.dbping.start(60) #60
if __name__ == "__main__":
db = sqlClass(adbapi.ConnectionPool("MySQLdb", cp_reconnect=True, host="", user="", passwd="", db=""))
reactor.callLater(2, db.dbping)
reactor.run()
дайте мне знать, как это работает для вас:)