|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).