我正在实现以下场景:
派生了100个线程,每个线程都通过单独的连接和运行时上下文连接到DB。每个线程将执行一个存储过程,该过程返回ref游标。
问题:有时对存储过程的调用永远不会返回(来自proc的存储过程调用挂起)
问题:如果proc对存储过程的调用没有在指定的时间内返回,有什么方法可以超时吗?
为什么不在线程中实现计时器?如果超时,请重新建立数据库连接,然后重试。
超时的唯一问题是,如果数据库服务器非常繁忙,它可能不会挂起,只是运行非常缓慢。
在POSIX平台上,如果您正在执行正常的阻塞系统调用,如read
、write
、wait
等。您可以使用select
或poll
来监视描述符,以确定数据何时可用以防止阻塞(带有相关的超时参数),也可以使用警报来触发一个信号,该信号将导致系统调用返回EINT
错误。
现在,阻塞某些特定于Oracle数据库的调用的调用,还是只是普通的系统调用?如果是前者(即,不是系统调用),那么您可以采取另一种方法,即您有一个超时警报,当它熄灭时,您会杀死任何仍在运行的线程。使用pthreads,将父线程中的每个子线程作为分离线程启动,这样,当调用成功完成时,它将自行结束,而无需手动终止它或调用pthread_join
。为所有pthread ID保留一个数组,当警报响起时,只需在主父线程的所有线程描述符上调用pthread_cancel
。对于已经完成的线程,这将毫无作用,但对于卡住的线程,它们将被杀死。
在生成任何子线程之前,您可以通过在主父线程中阻止来自所有线程的警报信号,然后只需使用sigwait
来监视来自父线程的超时警报的到达。这样做将防止任何子线程捕获报警信号(即,只有父线程将捕获并处理报警信号)。
数据库库可能已经支持超时功能。Sybase dblib确实如此。