(Обновление для ответа на вопрос Джонатана Леффлера ниже):
Мы используем Perl 5.8.7 и Oracle 11.1.0.7.0.
В соответствии с политикой компании, разработчики не имеют произвольного контроля над обновлением программного обеспечения. Для подачи предложения высшему руководству требуются месяцы (если оно будет одобрено) - я полагаю, что это не удивительно странная ситуация и для некоторых других компаний.
Я унаследовал программу от кого-то еще, покинувшего компанию, и обнаружил предупреждение о «выдаче отката () ...» из файла журнала приложения. Фактическая проблема "максимальное превышение open_cursor" была обнаружена после того, как я запустил DBI_TRACE = 2 = / tmp / trace.log имя_программы.pl .
Глядя на число $ dbh -> {ActiveKids}, $ dbh -> {Kids} и $ dbh -> {CachedKids}, я предполагаю, что максимальный открытый курсор равен 50, так как ошибка возникает после того, как она достигает 50.
Наши устаревшие производственные коды используют следующие модули:
- DBI - 1,48
- Има :: DBI - 0,33
- Класс :: DBI - 0,96
- Класс :: DBI :: Oracle - 0,51
- DBD :: Oracle - 1.16
По какой-то странной причине, обновление модуля до более новой версии невозможно: (
Приложение использует CDBI для обработки отношений с большим количеством таблиц. Ниже приведен упрощенный фрагмент кода:
JOB:
foreach my $job (@jobs) {
my @records = $job->record;
RECORD:
foreach my $record (@records) {
my @datas = $record->data;
DATA:
foreach my $data (@datas) {
....
}
}
}
, где каждый @ jobs , $ record и $ data - это объект таблицы, а внутренний внутренний цикл вызывает несколько других триггеров.
Где-то после нескольких циклов я получаю ошибку Oracle: максимум open_cursor превысил , а затем я получил ошибку от CDBI: выдача rollback () для дескриптора базы данных DESTROYE'd без явного отсоединять .
Я могу обойти это, undef -ing DBI CachedKids в самом внешнем цикле, с:
# somewhere during initialization
$self->{_this_dbh} = __PACKAGE__->db_Main();
....
JOB:
foreach my $job (@jobs) {
RECORD: ....
DATA: ....
$self->{_this_dbh}->{CachedKids} = undef;
}
Это правильный способ сделать это?
Или CDBI поддерживает способ очистки обработчика операторов так же, как DBI $ sth-> finish () ?
Спасибо.