私は一日中この問題に苦しんでいます..髪をすべて失う前に、ここで質問すると思いました.
説明
Rose::DB および PostgreSQL 8.4 (Debian Linux) で Perl 5.10.1 を使用しています。
「trans」オブジェクトを 1 つのトランザクション ブロック内に変更する必要があります (つまり、変更はすべて書き込まれるか、ロールバックされます)。しかし、私はそれを機能させることができません。
AutoCommit の ON と OFF の両方で試してみました。
以下のサンプル コードでは、$db は、スクリプトの開始時に確立された Rose::DB 接続です (使用: my $db = My::DB->new;)。すべての Rose::DB オブジェクトは基本クラス (My::Base) から継承します。この基本クラスには、DB 接続用の継承可能なサブがあります。
sub init_db
{
My::DB->new_or_cached
}
DB 接続オブジェクト (My::DB) には、接続文字列と設定が含まれています。
_ _PACKAGE_ _->use_private_registry;
_ _PACKAGE_ _->register_db(
driver => 'pg',
database => 'xx',
host => 'localhost',
username => 'xx',
password => 'xx',
connect_options => {
AutoCommit => 0, -- changed to suit SCENARIO 1 and 2 below
RaiseError => 1,
}
);
シナリオ 1: AutoCommit オフ
AutoCommit 0 と RaiseError 1
my $trans = shift;
eval {
$trans->... -- Make changes to object
$trans->save;
# die "testing"; -- Cause a rollback using "die"
$db->commit or die $db->error;
};
if ($@)
{
warn "aborted: $@";
eval {
$db->rollback;
};
}
ロールバック ケース: 動作します (変更は DB に書き込まれません)
コミットケース:失敗(DB に変更が書き込まれません)
シナリオ 2: AutoCommit オン
AutoCommit 1 と RaiseError 1
my $trans = shift;
eval {
$db->begin_work or die $db->error;
$trans->... -- Make changes to object
$trans->save;
# die "testing"; -- Cause a rollback using "die"
$db->commit or die $db->error;
};
if ($@)
{
warn "aborted: $@";
eval {
$db->rollback;
};
}
ロールバック ケース:失敗(変更が DB に書き込まれる)
コミットケース : Works (DB に書き込まれた変更)
あなたが提供できる助けやアドバイスは大歓迎です。
前もって感謝します。