我有下一个代码:
my $savepoint = $c->db->txn_scope_guard;
return $self->render( 'subnet/create', error => [ create => $@ ],
servers => $self->rows( 'Server' )->lookup,
) unless $subnet = eval{ $self->rows( 'Subnet' )->create( $subnet ) };
$savepoint->commit;
这里rows
是Mojolicious帮助程序,它提供对数据的访问。
sub model {
my( $c, $table_name ) = (shift,shift);
return $c->db->resultset( $table_name );
}
->db
也是帮手:
sub db { return $schema
//= DBIx::Class::Schema->connect( $DB->{ DSN }, @$DB{ qw/ USER PASS / }, {
AutoCommit => 1,
RaiseError => 1,
quote_char => '"',
})
});
当我创建$subnet
并且发生了唯一约束时(这里无论发生了哪种约束,实际上是在任何异常的情况下)我得到了错误:
DBIx::Class::Storage::DBI::_dbh_execute(): DBI Exception: DBD::Pg::st execute failed: ERROR: current transaction is aborted, commands ignored until end of transaction block [for Statement "SELECT "me"."id", "me"."hostname" FROM "servers" "me" ORDER BY hostname"] at ...
这是当我用eval{ ... }
捕获异常时当前事务被中止而我无法$self->rows( 'Server' )->lookup
是否有办法在发生异常后访问服务器数据?
答案 0 :(得分:0)
似乎我找到了答案,因为更仔细地阅读错误信息:
...命令被忽略,直到事务块结束
因此,当异常发生时,我强制结束事务块:
$c->db->txn_rollback;
代码:
my $savepoint = $c->db->txn_scope_guard;
unless( $subnet = eval{ $self->rows( 'Subnet' )->create( $subnet ) } ) {
my $e = $@; # $@ may be changed before `create => $@`
undef $savepoint; # Or the same: $c->db->txn_rollback;
return $self->render( 'subnet/create', error => [ create => $e ],
servers => $self->rows( 'Server' )->lookup,
);
}
$savepoint->commit;