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 ответ
Возможно, вы открываете более одного подключения к базе данных. Поведение точно соответствует ожидаемому, если соединение, которое вы фиксируете, не совпадает с соединением, в котором находится транзакция.
Я предлагаю вам пересмотреть поток вашей программы, чтобы убедиться, что у вас есть только одно соединение.