我想用时间线程终止正在运行的查询。我已经尝试过不同的实现,但似乎没有任何效果。
现在我调用函数 executeTimedQuery,它启动一个 10 秒计时器,如果查询运行时间过长,该计时器就会执行。一开始 self.cursor.execute(self.query) 开始运行,这是我想在 10 秒后终止的长时间运行的查询。由于某种原因,即使计时器中的函数被启动,游标仍在运行长时间运行的查询并且不运行 KILL CONNECTION {pId};。它等待长查询完成,然后在最后终止连接。
我在这里做错了什么,最好的解决方法是什么?我现在非常渴望找到解决方案。 :/
到目前为止,我有以下代码:
def killDBConnection(self, processId):
'''
This takes in a processId, which is the mysql cursor connection process
id.
'''
killQuery = 'KILL CONNECTION {pId};'.format(pId=processId)
try:
self.cursor.execute(killQuery)
except:
print('Testing')
return 'temp'
def executeTimedQuery(self, ret):
'''
This takes in a dictionary.
'''
pID = self.getProcessId()
try:
Timer(10.0, self.killDBConnection, [pID]).start()
self.cursor.execute(self.query)
ret['executable'] = True
ret['data'] = self.cursor.fetchall()
ret['headers'] = tuple([col[0] for col in self.cursor.description])
t.cancel()
except:
print('executeTimedQuery - Last executed query: ', self.cursor._last_executed)
return ret
最佳答案
上面的示例一直失败,因为我试图在仍在处理长时间运行的查询的同一个 mysql 线程上执行“KILL PID”查询。 “KILL PID”仅在长时间运行的查询完成后才运行,这不是我想要的。长话短说,终止长时间运行的查询的方法是打开另一个连接,使用“KILL PID”关闭长时间运行的查询。现在,在执行长时间运行的查询之前获得正确的 PID 是必不可少的。
最初,我编写了一个类来初始化一个连接和游标,并且可以在函数内的任何位置访问。我没有这样做,而是编写了一个可以在调用时为我创建连接的函数。我为长时间运行的查询初始化了一个连接,并为 kill 查询函数初始化了一个连接。我从长时间运行的查询中获取进程 ID,然后使用定时线程在一定时间后启动“KILL PID”。
这是一个骨架/大部分代码:
class QueryWithTimeout(object):
def __init__(self, db, query, totalTimeout):
self.db = db
self.query = query
self.totalTimeout = totalTimeout
...
def setUpConnection(self):
connection = connections[self.db]
cursor = connection.cursor()
return cursor, connection
def getProcessId(self, cursor):
processID = 'SELECT CONNECTION_ID();'
cursor.execute(processID)
processIDOutput = cursor.fetchall()[0]
return processIDOutput[0]
def killDBConnection(self, processId, ret):
killCursor, killConnection = self.setUpConnection()
killQuery = 'KILL {pId};'.format(pId=processId)
try:
killCursor.execute(killQuery)
except:
print('TEMP')
def executeTimedQuery(self, pId, cursor):
ret = {...}
timeoutCall = Timer(self.totalTimeout, self.killDBConnection, [pId, ret])
timeoutCall.start()
try:
cursor.execute(self.query)
#timeoutCall.cancel()
except:
return ret
ret[...] = ...
return ret
def processTimedQuery(self):
queryCursor, queryConnection = self.setUpConnection()
queryProcessId = self.getProcessId(queryCursor)
return self.executeTimedQuery(queryProcessId, queryCursor)
作为旁注,我尝试了各种方法,但都失败了,但是这个。
关于python - 使用定时线程终止查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51315488/