(更新以回答下面Jonathan Leffler提出的问题):
我们正在运行Perl 5.8.7和Oracle 11.1.0.7.0。
由于公司的政策,开发人员对软件升级没有任意控制。向高层管理人员提交建议需要数月才能得到跟进(如果获得批准) - 我想其他几家公司也不会出现奇怪的情况。
我从其他人离开公司继承了该程序,并从应用程序日志文件中发现了“发出rollback()...”的警告。运行 DBI_TRACE = 2 = / tmp / trace.log program_name.pl 后,找到了“超出最大open_cursor”的实际问题。
查看$ dbh-> {ActiveKids},$ dbh-> {Kids}和$ dbh-> {CachedKids}的数量,我假设最大打开游标为50,因为错误发生在它之后达到50。
我们的传统生产代码正在使用这些模块:
出于某些奇怪的政策原因,无法将模块升级到更新版本:(
应用程序依赖于使用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 - 最外层循环上的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()相同的方式清除语句句柄?
感谢。
答案 0 :(得分:2)
在某些时候,您必须解释为什么无法升级到更接近当前版本的软件。您没有提到您使用的是哪个版本的Perl,或者是哪个版本的Oracle;不知何故,我怀疑它既不是5.10.1也不是11gR2。
当前版本:
最近发生了什么变化?为什么你突然发现一个大概是非常稳定的软件问题?这是新代码吗?
使用普通的DBI,当你取消一个语句句柄(例如,让它超出范围)时,与它相关的资源会被释放 - 或多或少吵闹。但是,Class :: DBI和DBI之间有足够的基础设施,很难说它是如何映射的。