[email protected] (Florian Weimer) writes:
> Is there are ready-to-use transaction wrapper for DBD:Pg?  I'm looking
> for somehting which can be used like this:
>
>     my $connect_args = [$data_source, $username, $auth, \%attr];
>     transact $connect_args, sub {
>       my ($dbh) = @_;
>       $dbh->begin_work;
>       ...
>       $dbh->commit;
>     };
>
> The transact subroutine should abort the transaction if the passed sub
> dies.  For certain exceptions, the sub should be called again to retry
> the transaction.  The database handle should be cached.
>
> This is somewhat PostgreSQL-specific because there are three cases:
> permanent errors (such as SQL syntax errors, or non-SQL exceptions),
> transient errors which will go away when the transaction is retried
> within the same connection (such as serialization failures and certain
> types of UNIQUE constraint violations), and errors which will likely go
> away when the transaction is retried with a fresh connection (due to
> server restart, for example).
>
> This is not very difficult to write as such, but getting the error code
> list right is a bit delicate.

There is no way in heaven or hell to deal cleanly with 'connection
aborts' using the stock DBD::Pg because that won't consistently inform
an application that 'a possibly transient communication problem
ocurred' (let alone providing even more specialized error
information). I happen to know this because I have implemented a
couple of application-specific facilities for dealing transparently
with such transient failures in the last couple of years[*] and this
always involved another round of dbdimp.c changes when the thing blew
up for another time in another different place. I think I have finally
managed to nail that for the DBD::Pg I'm using, though, and a 'public
patch' is available here:

https://rt.cpan.org/Public/Bug/Display.html?id=66792

[*] My general opinion on 'third-party code written to solve
development problems' is that it is generally not worth the effort to
become familiar with that, especially considering that adapting or at
least fixing it will become necessary at some point, except if using
it means saving a significant amount of coding effort, with
significant supposed to mean '>> 1000 LOC just to provide the required
functionality'. Typically, what is actually required will need a few
hundred lines of code and in this case, the problems lurking in the
(also typically) thousands if not ten or even hundred thousands of
lines of code of the 'one size fits all two times plus a kitchen sink'
'seriously bored programmer' solution are not worth dealing with.

Reply via email to