On Mon, Feb 16, 2004 at 07:46:49PM -0600, Jay Hannah wrote:
> > Incidentally, you already don't get the warning during global
> > destruction, so it isn't that reliable.
> 
> I ran a little test against all our productions RDBMSs. As luck would have it, it 
> seems that it is being thrown in global destruction in the 2 DBD's I use the most. I 
> didn't realize until now that it's not being thrown in the others.
> 
> DBD::Informix -> Informix 9.3:            Issuing rollback() for database...
> DBD::Informix -> Informix SE (ancient):   No warning
> DBD::Sybase -> freetds -> MS-SQL server:  Issuing rollback() for database...
> DBD::Proxy -> DBD::Oracle -> Oracle (v?): No warning
> DBD::Oracle -> Oracle (v?):               No warning
> DBD::mysql:                               No warning

That's odd.  The warning is actually generated by what's known as
the "driver template" code that all compiled drivers should use
(though some don't). Here's the code in DBI 1.40:

 if (DBIc_ACTIVE(imp_dbh)) {
    /* The application has not explicitly disconnected. That's bad.     */
    /* To ensure integrity we *must* issue a rollback. This will be     */
    /* harmless if the application has issued a commit. If it hasn't    */
    /* then it'll ensure integrity. Consider a Ctrl-C killing perl      */
    /* between two statements that must be executed as a transaction.   */
    /* Perl will call DESTROY on the dbh and, if we don't rollback,     */
    /* the server may automatically commit! Bham! Corrupt database!     */
    if (!DBIc_is(imp_dbh,DBIcf_AutoCommit)) {
        if (DBIc_WARN(imp_dbh) && (!dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3))
             warn("Issuing rollback() for database handle being DESTROY'd without 
explicit disconnect()");
        dbd_db_rollback(dbh, imp_dbh);                  /* ROLLBACK! */
    }
    dbd_db_disconnect(dbh, imp_dbh);
    DBIc_ACTIVE_off(imp_dbh);   /* ensure it's off, regardless */
 }

All drivers using the driver template code should exhibit the same
behaviour for applications where AutoCommit is off, Warn is on
(which it is by default), and the DESTROY happens before global
destruction.

I suspect in some of the cases you quote above AutoCommit is not off,
or the DESTROY is happening during global destruction.

Tim.

Reply via email to