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