DBM :: Deep:交易问题

时间:2011-02-26 09:46:34

标签: database perl transactions dbm

我从未完成交易(就编程而言),因此我不知道我的脚本或其他内容是否有问题:

#!/usr/bin/env perl
use warnings;
use 5.012;
use DBM::Deep;

my $db = DBM::Deep->new( 'foo.db' );

my $trans = $db->supports( 'transactions' );
say 'Does ', $trans ? '' : 'NOT ', 'support transactions'; 

$db->{key} = 'value';
$db->begin_work;
$db->{key1} = 'value2';
$db->rollback;
$db->{key1} = 'value1';
$db->commit;

输出:

# Does support transactions
# DBM::Deep: Cannot allocate transaction ID at ./perl1.pl line 12

评论的一部分:

my $db = DBM::Deep->new( file => 'my.db', num_txns => 1 );

$db->{key} = 'value';
$db->begin_work;
$db->{key1} = 'value2';
$db->rollback;
$db->begin_work;
$db->{key1} = 'value1';
$db->commit;

2 个答案:

答案 0 :(得分:1)

根据documentation rollback命令结束交易。

  

rollback()这会丢弃更改   在交易内完成了   主线并结束交易。

因此,您需要在回滚后启动新事务。

$db->{key} = 'value';
$db->begin_work;
$db->{key1} = 'value2';
$db->rollback;
$db->begin_work;
$db->{key1} = 'value1';
$db->commit;

或者您可以执行类似

的操作
sub my_rollback {
  my $db = shift;
  $db->rollback();
  $db->begin_work();
}

$db->{key} = 'value';
$db->begin_work;
$db->{key1} = 'value2';
my_rollback $db;
$db->{key1} = 'value1';
$db->commit;

或者用一点黑魔法,你可以保持OO风格

sub my_rollback {
  my $db = shift;
  $db->rollback();
  $db->begin_work();
};
{
  no strict 'refs';
  *{'DBM::Deep::my_rollback'} = \&my_rollback;
}

$db->{key} = 'value';
$db->begin_work;
$db->{key1} = 'value2';
$db->my_rollback;
$db->{key1} = 'value1';
$db->commit;

答案 1 :(得分:1)

很抱歉花了这么长时间来回答这个问题 - 我几天前才发现它。 (我是DBM :: Deep的维护者。)

问题是num_txns仅在创建文件时设置。 (这是因为DBM文件在磁盘上的布局。)一旦创建了DBM文件,就会从文件中读取num_txns值,并在调用new()时忽略该值。因此,一旦您将调用更改为指定num_txns,除非您还使用了新的DBM文件,否则它将无济于事。

虽然我无法在不显着改变DBM文件结构的工作方式的情况下改变这种行为(这可能是一个好主意,但这是一件大事),但您应该已经收到警告,应该有更好的文档。我已经打开https://github.com/robkinyon/dbm-deep/issues/12来跟踪此问题及其修复程序。