Here's my first suggestion towards giving the various DBD modules more consistent behaviour, which would aid in both database portability and in the construction of a common test suite.

This suggestion affects DBD modules for databases that have support for transactions; it should have no impact on DBD modules for databases that lack said support, and hence are auto-commit all the time.

I reference this portion of the DBI user documentation, under disconnect():

The transaction behaviour of the disconnect method is, sadly, undefined. Some database systems (such as Oracle and Ingres) will automatically commit any outstanding changes, but others (such as Informix) will rollback any outstanding changes. Applications not using AutoCommit should explicitly call commit or rollback before calling disconnect.

The database is automatically disconnected by the DESTROY method if still connected when there are no longer any references to the handle. The DESTROY method for each driver should implicitly call rollback to undo any uncommitted changes. This is vital behaviour to ensure that incomplete transactions don't get committed simply because Perl calls DESTROY on every object before exiting. Also, do not rely on the order of object destruction during "global destruction", as it is undefined.

Generally, if you want your changes to be commited or rolled back when you disconnect, then you should explicitly call "commit" or "rollback" before disconnecting.

I suggest that the disconnect() function follow the same behaviour as DESTROY for how transactions are dealt with. Or in other words, any current transaction should *always* be rolled back when a database connection is closed, regardless of how it is closed. The DBD modules should do this by themselves, and hence the users of DBI can count on the "shortest/simplest path" (no explicit c/r pre disc) always being consistent. They know that they must always explicitly commit() transactions (or use auto-commit), or changes won't be saved, period.

Now, if you think my suggestion to always-rollback vs always-commit is arbitrary, I suggest that always-rollback is a safer default option.

Since this suggestion has nothing to do with SQL, I believe it is well within the domain of things to implement in the DBI/DBD domain, and should not have to be the domain of wrapper modules.

I will also note that this change should not break any user applications if they were doing the "right thing" to begin with, which is "be explicit", as the documentation says. Only applications that counted on undefined default behaviour to be a certain way, which is "commit", and used a database that did just that, might break.

Any feedback?  Can we do this thing?  Or are there any good reasons not to?

-- Darren Duncan

Reply via email to