1

我整天都在为这个问题苦苦挣扎。在我松开所有头发之前,我想我会在这里问。

描述

我将 Perl 5.10.1 与 Rose::DB 和 PostgreSQL 8.4(在 Debian Linux 上)一起使用。

我需要对我的“trans”对象进行一些更改,使其位于单个事务块中(即更改全部写入或回滚)。但是,我就是无法让它工作。

我已经在 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:自动提交关闭

自动提交 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;
    };
}

回滚案例:​​有效(没有更改写入数据库)

提交案例:失败(没有更改写入数据库)

场景 2:自动提交开启

自动提交 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;
    };
}

回滚案例:​​失败(写入数据库的更改)

提交案例:有效(写入数据库的更改)

您可以提供的任何帮助或建议将不胜感激。

提前致谢。

4

1 回答 1

2

您可能打开了多个数据库连接。如果您提交的连接与具有事务的连接不同,则该行为正是人们所期望的。

我建议您重新检查您的程序流程,以确保您只有一个连接。

于 2013-02-18T08:26:01.427 回答