Я создаю УСПОКОИТЕЛЬНЫЙ API, который должен получить доступ к базе данных. Я использую Restish, Oracle и SQLAlchemy. Однако я попытаюсь структурировать свой вопрос максимально в общем, не принимая во внимание Restish или другие веб-API.
Я хотел бы смочь установить тайм-аут для соединения, выполняющего запрос. Это должно гарантировать, что от длительных запросов отказываются, и отброшенное соединение (или перерабатывают). Этот тайм-аут запроса может быть глобальным значением, значением, я не должен изменять его на создание соединения или запрос.
Учитывая следующий код:
import cx_Oracle
import sqlalchemy.pool as pool
conn_pool = pool.manage(cx_Oracle)
conn = conn_pool.connect("username/p4ss@dbname")
conn.ping()
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM really_slow_query")
print cursor.fetchone()
finally:
cursor.close()
Как я могу изменить вышеупомянутый код для установки тайм-аута запроса на нем? Этот тайм-аут будет также относиться к созданию соединения?
Это подобно какой java.sql. setQueryTimeout оператора (международные секунды) метод делает в Java.
Спасибо
Вы можете посмотреть, как настроить PROFILE в Oracle, чтобы завершить запросы после определенного количества логических_представлений_пер_вызовов и / или cpu_per_call
Тайм-аут с помощью системного сигнала
Вот как использовать тайм-аут операционной системы для этого. Он общий и работает не только для Oracle.
import signal
class TimeoutExc(Exception):
"""this exception is raised when there's a timeout"""
def __init__(self): Exception.__init__(self)
def alarmhandler(signame,frame):
"sigalarm handler. raises a Timeout exception"""
raise TimeoutExc()
nsecs=5
signal.signal(signal.SIGALRM, alarmhandler) # set the signal handler function
signal.alarm(nsecs) # in 5s, the process receives a SIGALRM
try:
cx_Oracle.connect(blah blah) # do your thing, connect, query, etc
signal.alarm(0) # if successful, turn of alarm
except TimeoutExc:
print "timed out!" # timed out!!
для запроса вы можете посмотреть на таймер и вызов conn.cancel().
что-то в этом роде:
t = threading.Timer(timeout,conn.cancel)
t.start()
cursor = conn.cursor()
cursor.execute(query)
res = cursor.fetchall()
t.cancel()