此代码在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
失效,这将永远挂起!
它与OCIPing
无关 - 如果我替换:
ping()
使用:
cursor = conn.cursor()
cursor.execute('SELECT 1 FROM DUAL') # HANG FOREVER AS WELL
这也会挂起。
我正在使用 SQL * Plus:2013年11月6日星期三12:17:09发布11.2.0.3.0版本。
我尝试在线程中包装此代码并等待同时杀死线程,但这不起作用。这段代码自己创建一个线程,而python无法杀死它。你有什么想法如何恢复?
答案 0 :(得分:0)
简短的回答是使用try / except / finally块,但如果部分代码真的在等待永远不会满足的条件,那么你需要做的是实现内部超时。有很多方法可以做到这一点。您可以根据需要调整solution to this problem以完成此任务。
希望这有帮助。
答案 1 :(得分: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
)。
如果发现异常,请尝试重试。
答案 2 :(得分:-1)
如果你想要密切联系,请尝试
conn.close()