Perl и Rose::DB Postgres Сделки

Я боролся с этой проблемой весь день... думал, что я спрошу здесь, прежде чем я потеряю все свои волосы.

Описание

Я использую Perl 5.10.1 с Rose::DB и PostgreSQL 8.4 (в Debian Linux).

Мне нужно, чтобы некоторые изменения в моих "trans" объектах были в одном блоке транзакции (т.е. изменения либо все записываются, либо откатываются). Однако я просто не могу заставить его работать.

Я пробовал это и с AutoCommit ВКЛ и ВЫКЛ.

В приведенном ниже примере кода $ db - это соединение Rose::DB, установленное в начале скрипта (используя: my $db = My::DB->new;). Все объекты Rose::DB наследуются от базового класса (My::Base). Этот базовый класс имеет наследуемую подпрограмму для соединения с БД:

sub init_db
{
    My::DB->new_or_cached
}

Объект подключения к БД (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 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: Автокоммит включен

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;
    };
}

Случай отката: ошибка (изменения записываются в БД)

Фиксация: работает (изменения записываются в БД)

Любая помощь или совет, который вы можете предложить, будет принята с благодарностью.

Заранее спасибо.

1 ответ

Решение

Возможно, вы открываете более одного подключения к базе данных. Поведение точно соответствует ожидаемому, если соединение, которое вы фиксируете, не совпадает с соединением, в котором находится транзакция.

Я предлагаю вам пересмотреть поток вашей программы, чтобы убедиться, что у вас есть только одно соединение.

Другие вопросы по тегам