0

这段代码在 python 中,但基本上它正在使用OCI,所以应该可以用任何其他语言重现:

import cx_Oracle as db
dsn = '(DESCRIPTION =(CONNECT_TIMEOUT=3)(RETRY_COUNT=1)(TRANSPORT_CONNECT_TIMEOUT=3)(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = SOME_HOST)(PORT = 1531)))(CONNECT_DATA =(SERVICE_NAME = SOME_NAME)))'
connect_string = "LOGIN/PASSWORD@%s" % dsn
conn = db.connect(connect_string)
conn.ping() # WILL HANG FOREVER!!!

如果SOME_HOST是down,这将永远挂起!

它与OCIPing- 如果我替换:

ping()

和:

cursor = conn.cursor()
cursor.execute('SELECT 1 FROM DUAL') # HANG FOREVER AS WELL

这也会挂起。

我正在使用SQL*Plus: Release 11.2.0.3.0 Production on Wed Nov 6 12:17:09 2013

我尝试将此代码包装在线程中并等待与杀死线程相同的时间,但这不起作用。这段代码自己创建了一个线程,python 不可能杀死它。你对如何恢复有任何想法吗?

4

3 回答 3

0

简短的回答是使用 try/except/finally 块,但如果您的部分代码确实在等待永远不会满足的条件,那么您需要做的是实现内部超时。有很多方法可以做到这一点。您可以根据您的需要调整此问题的解决方案以完成此操作。

希望这可以帮助。

于 2014-01-21T03:04:05.650 回答
0

我在打断时遇到了同样的问题conn.ping()
现在我使用下一个构造:

from threading import Timer

pingTimeout = 10 # sec

# ...

def breakConnection():
    conn.cancel()
    connection = False

try:
    t = Timer(pingTimeout, breakConnection)
    cursor = conn.cursor()
    cursor.execute('SELECT 1 FROM DUAL')
    t.close()
    cursor.close()
except Exception:
    connection = False

if not connection:
    print 'Trying to reconnect...'
    # ...

这是一种肮脏的方式,但它有效。

检查连接是否可用的真正方法是执行您要运行的应用程序语句(我不是说SELECT 1 FROM DUAL)。然后尝试重试,如果您捕获到异常。

于 2018-08-17T13:51:34.800 回答
-1

如果你想关闭连接试试

conn.close()
于 2015-12-19T23:40:19.227 回答