2010-03-03 40 views
9

Tôi đang tạo một API RESTful cần truy cập cơ sở dữ liệu. Tôi đang sử dụng Restish, Oracle và SQLAlchemy. Tuy nhiên, tôi sẽ cố gắng đặt câu hỏi của mình một cách rộng rãi nhất có thể, mà không cần tính đến các API của Restish hoặc các API web khác.Đặt thời gian chờ kết nối cơ sở dữ liệu bằng Python

Tôi muốn có thể đặt thời gian chờ cho kết nối thực hiện truy vấn. Điều này đảm bảo rằng các truy vấn chạy dài bị bỏ qua và kết nối bị loại bỏ (hoặc tái chế). Thời gian chờ truy vấn này có thể là một giá trị toàn cầu, có nghĩa là, tôi không cần phải thay đổi nó cho mỗi truy vấn hoặc tạo kết nối.

Với đoạn mã sau:

import cx_Oracle 
import sqlalchemy.pool as pool 

conn_pool = pool.manage(cx_Oracle) 
conn = conn_pool.connect("username/[email protected]") 
conn.ping() 

try: 
    cursor = conn.cursor() 
    cursor.execute("SELECT * FROM really_slow_query") 
    print cursor.fetchone() 
finally: 
    cursor.close() 

Làm thế nào tôi có thể sửa đổi các mã trên để thiết lập một thời gian chờ truy vấn trên nó? Thời gian chờ này cũng sẽ áp dụng cho việc tạo kết nối?

Điều này tương tự với phương thức setQueryTimeout (int giây) của java.sql.Statement trong Java.

Cảm ơn

+0

Xin chào, tôi thấy rằng không có câu trả lời nào được chấp nhận, bạn có tìm thấy giải pháp nào khác cho vấn đề này không? – Ib33X

+0

Không, tôi không thể thực hiện công việc này. Các giải pháp được đề xuất cho đến nay chỉ đơn giản là không hoạt động. – oneself

+0

Tại sao 'conn.cancel()' không hoạt động? Điều gì sẽ xảy ra khi bạn thử giải pháp của Dmitry? – alldayremix

Trả lời

0

Bạn có thể nhìn vào thiết lập PROFILE s trong Oracle để chấm dứt các truy vấn sau khi một số lượng nhất định logical_reads_per_call và/hoặc cpu_per_call

-3

Timing Out với hệ thống báo động

Dưới đây là cách sử dụng thời gian chờ của hệ điều hành để thực hiện việc này. Đó là chung chung, và làm việc cho những thứ khác ngoài 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!! 
+0

Điều này dường như không hoạt động. Oracle không bị gián đoạn. – oneself

+0

Tất nhiên Oracle (trên máy chủ) không bị gián đoạn - bạn nói rằng bạn muốn "từ bỏ truy vấn dài hạn", có nghĩa là bạn chỉ cần từ bỏ việc chờ phản hồi. Nếu bạn muốn thực sự làm cho Oracle ngừng chạy truy vấn - đó là một điều hoàn toàn khác, và không quá dễ dàng - bạn sẽ phải "giết phiên" trên máy chủ ... –

+1

Điều tôi muốn nói là truy vấn tiếp tục chạy không bị gián đoạn trên máy khách. – oneself

11

cho truy vấn, bạn có thể xem cuộc gọi hẹn giờ và conn.cancel().

cái gì đó trong những dòng:

t = threading.Timer(timeout,conn.cancel) 
t.start() 
cursor = conn.cursor() 
cursor.execute(query) 
res = cursor.fetchall() 
t.cancel() 
+0

Điều này hoạt động rất tốt, cảm ơn! Đây là cách tôi có thể giết các yêu cầu dài hạn của mình. – Emmanuel

3

Trong linux thấy /etc/oracle/sqlnet.ora,

sqlnet.outbound_connect_timeout= value

cũng có các tùy chọn:

tcp.connect_timeout và sqlnet .expire_time, chúc may mắn!

+0

Tôi nghĩ rằng đây là để kết nối, không thực hiện tuyên bố. – Glyph

+0

Đó là một giải pháp làm việc, hãy thử nó;) – BetarU

Các vấn đề liên quan