set_uk has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to create a module that sets up environment variables from another module, creates a database handle and passes it back to the calling script.
I understand that an object exists as long as there is a reference to it but cant quite see why this code generates the following errors when it tries to destroy the dbh even though it is always an object in the hash? No doubt I am confused about a fundamental here.
Issuing rollback() for database handle being DESTROY'd without explici +t disconnect() at ./poe_ctrl.pl line 38. $VAR1 = bless( { '_dbh' => bless( {}, 'DBI::db' ) }, 'SDU::DB' ); Issuing rollback() for database handle being DESTROY'd without explici +t disconnect(). ------------------------------------------------------------ Script to create the connection poe_ctrl.pl use warnings; use strict; use Data::Dumper; use POE qw(Wheel::Run Filter::Reference); use SDU::CommandIterator; use SDU::DB; use SDU::Config; sub MAX_CONCURRENT_TASKS () { 5 } # Create database connection my $dbh = SDU::DB->new; print Dumper($dbh); exit; ------------------------------------------------------------ Package to create the connection package SDU::DB; require 5.008 ; use SDU::Config; use strict; use Carp; use Carp qw(cluck); use DBI; use DBI qw(:sql_types); use DBD::Oracle; use DBD::Oracle qw(:ora_types); use TNBException; sub new { my $class = shift; my $SC = SDU::Config->new; my $DB = { _dbh => &ConnectToOracle($SC) }; my $DC = &ConnectToOracle($SC); my $self = bless $DB, $class; return $self; } sub ConnectToOracle{ my ($SC) = @_; $ENV{ORACLE_HOME}=$SC->{ORA_HOME}; $ENV{TWO_TASK}=$SC->{ORA_SID}; $ENV{ORACLE_SID}=$SC->{ORA_SID}; my $combined=$SC->{ORA_USER}."@".$SC->{ORA_SID}; my $trace_level=0; my $dbh = undef; $dbh = DBI->connect('dbi:Oracle:',$combined , $SC->{ORA_PASS}) or +throw TNBCriticalException($dbh->errstr); $dbh->func( 1000000, 'dbms_output_enable' ); $dbh->{RaiseError} = 1; $dbh->{PrintError} = 0; $dbh->{AutoCommit} = 0; $dbh->trace($trace_level); return $dbh; } 1;

Replies are listed 'Best First'.
Re: DBI and Modules
by ptkdb (Monk) on Oct 17, 2003 at 17:48 UTC
    I think the answer is in the error message itself. You need to issue an explicit disconnect before your program exits. This is probably coming out of the database driver, since the quick skimming of DBI examples I've done doesn't explicitely seem to require a disconnect, but does urge it.

    With a perl object such as you have here, this can be guaranteed with a DESTROY method:

    =pod =item DESTROY Called when the last reference to the object goes away. =cut sub DESTROY { my($self) = @_ ; if( $self->{_dbh } ) { # check in case it was deallocated somewhere else $self->{_dbh}->disconnect() ; } }
Re: DBI and Modules
by set_uk (Pilgrim) on Oct 17, 2003 at 15:50 UTC
    Ignore me - forgot to remove old testing code:- <code> my $DC = &ConnectToOracle($SC); <\code> which created a 2nd dbh. Time to stop for the day I think