2017-10-21 151 views
1

我有下面的代碼:如何在發生異常時訪問數據庫數據?

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'時我需要查找。 –

回答

0

我似乎找到了答案,因爲讀取錯誤消息更仔細:

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

相關問題