如何在发生异常时访问数据库数据?

问题描述:

我有下面的代码:如何在发生异常时访问数据库数据?

my $savepoint = $c->db->txn_scope_guard; 
return $self->render('subnet/create', error => [ create => [email protected] ], 
    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并且发生唯一约束(这里有无论哪个约束出现,实际上任何异常的情况下),我得到了错误:

这是当我发现异常与eval{ ... }当前交易被中止,我不能做$self->rows('Server')->lookup

有没有办法在异常发生后访问服务器数据?

+0

为什么不在创建之前进行查找? – xxfelixxx

+0

,因为当用户选择“POST”时,我不需要查找数据。只有在渲染形式为'subnet/create'时我需要查找。 –

我似乎找到了答案,因为读取错误消息更仔细:

... commands ignored until end of transaction block

所以我强迫事务块结束时,异常发生:

$c->db->txn_rollback; 

代码:

my $savepoint = $c->db->txn_scope_guard; 
unless($subnet = eval{ $self->rows('Subnet')->create($subnet) }) { 
    my $e = [email protected]; # [email protected] may be changed before `create => [email protected]` 
    undef $savepoint; # Or the same: $c->db->txn_rollback;  
    return $self->render('subnet/create', error => [ create => $e ], 
     servers => $self->rows('Server')->lookup, 
    ); 
} 
$savepoint->commit; 
+0

您应该添加对该引用的引用,以便其他人可以读取其上下文。 – xxfelixxx

+1

@xxfelixxx是错误消息的一部分 – ysth

+1

您应该将$ @保存在except块中的其他变量中;如果您先将其他代码放入,可能会清除或更改 – ysth