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