Как истечь время, если хранимая процедура proc не возвращается - PullRequest
1 голос
/ 08 июня 2011

Я реализую следующий сценарий:

100 потоков создаются, и каждый поток подключается к БД с отдельными подключениями и контекстами времени выполнения. Каждый поток будет выполнять хранимую процедуру, которая возвращает курсор ref.

Проблема: иногда вызов хранимой процедуры никогда не возвращается (зависает хранимая процедура из proc)

Вопрос: есть ли способ прервать вызов хранимой процедуры из proc, если она не возвращается в указанное время?

Ответы [ 3 ]

1 голос
/ 08 июня 2011

Почему бы не реализовать таймер в ваших потоках? Если время истекло, восстановите подключение к базе данных и повторите попытку.

Единственная проблема с тайм-аутами состоит в том, что если сервер базы данных очень занят, он может не зависать, просто работает очень медленно.

0 голосов
/ 09 июня 2011

Библиотека базы данных может уже поддерживать функцию тайм-аута.Sybase dblib делает.

0 голосов
/ 08 июня 2011

На платформе POSIX, если вы выполняете обычные системные вызовы блокировки, такие как read, write, wait и т. Д., Вы можете использовать select или poll для отслеживания дескриптора, когда данные доступен для предотвращения блокировки (с соответствующим параметром тайм-аута) или использования аварийного сигнала для запуска сигнала, который вызовет системный вызов с ошибкой EINT.

Теперь, вызовы, которые блокируют некоторые специфические вызовы Oracle DB, или это просто обычные системные вызовы? Если первое (то есть, не системные вызовы), то вы можете использовать другой подход, когда у вас есть тайм-аут, когда он отключается, вы убиваете все потоки, которые все еще работают. Используя pthreads, запускайте каждый дочерний поток из родительского потока в качестве отдельного потока, чтобы после успешного завершения вызова он завершился сам, без необходимости вручную завершать его или вызывать pthread_join. Сохраняйте массив для всех идентификаторов pthread, а когда сработает сигнализация, просто вызовите pthread_cancel для всех дескрипторов потока из основного родительского потока. Для завершенных потоков это ничего не сделает, но для застрявших потоков они будут уничтожены.

Вы можете заблокировать сигнал тревоги из всех потоков, заблокировав его в главном родительском потоке перед тем, как создавать дочерние потоки, а затем просто использовать sigwait, чтобы отслеживать поступление тревоги тайм-аута из родительского потока. Это предотвратит перехват сигнала тревоги любым дочерним потоком (т. Е. Только родитель будет перехватывать и обрабатывать сигнал тревоги).

...