Subject: | Bug: Spurious rollback when commit fails |
Date: | Fri, 18 Sep 2015 10:38:17 +0200 |
To: | <bug-DBIx-Class [...] rt.cpan.org> |
From: | Christopher Travers <cpt [...] novozymes.com> |
This is reproduced in DBIx::Class from Ubuntu 14.04, but the code didn't
look that different for most recent so I figured it was almost certain
to exist there too.
Scenario: Initially deferred constraints and PostgreSQL violated by a
$schema->txn_do() transaction.
This would be common in cases where you might have a circular foreign
key constraint and so you check one at insert time and the other at
commit time (in our case, it is slightly different -- it is a custom
constraint trigger but one which enforces something conceptually similar).
What happens:
rollback ineffective with AutoCommit enabled
at
DBIx::Class::Storage::DBI::_exec_txn_rollback(/usr/share/perl5/DBIx/Class/Storage/DBI.pm
line 1552, <DATA>:751)
at
DBIx::Class::Storage::txn_rollback(/usr/share/perl5/DBIx/Class/Storage.pm:255)
at
DBIx::Class::Storage::DBI::txn_rollback(/usr/share/perl5/DBIx/Class/Storage/DBI.pm:1538)
at <eval>(/usr/share/perl5/DBIx/Class/Storage/BlockRunner.pm:174)
at
DBIx::Class::Storage::BlockRunner::__ANON__(/usr/share/perl5/DBIx/Class/Storage/BlockRunner.pm:174)
at
Context::Preserve::preserve_context(/usr/share/perl5/Context/Preserve.pm:27)
at
DBIx::Class::Storage::BlockRunner::_run(/usr/share/perl5/DBIx/Class/Storage/BlockRunner.pm:221)
at
DBIx::Class::Storage::BlockRunner::run(/usr/share/perl5/DBIx/Class/Storage/BlockRunner.pm:112)
at
DBIx::Class::Storage::txn_do(/usr/share/perl5/DBIx/Class/Storage.pm:189)
at
DBIx::Class::Storage::DBI::txn_do(/usr/share/perl5/DBIx/Class/Storage/DBI.pm:816)
at
DBIx::Class::Schema::txn_do(/usr/share/perl5/DBIx/Class/Schema.pm:656)
....
DBIC_TRACE shows that the commit that raised the error was followed by a
rollback. There was no additional begin transaction statement, and
tracing the code via the call stack shows that the commit occurs and the
exception is handled properly.
Impact: This is primarily an issue of clarity of the logs. An error
like this could indicates a transaction was committed twice but it
doesn't say enough by itself that one can quickly/easily determine that
it was an exception on commit. This means that while the bug is itself
harmless it can make it harder to spot harmful bugs in the log files,
and that can eventually result in data loss (when combined with other
bugs of course).