2

我从未做过交易(在编程方面),因此我不知道我的脚本是否有问题或其他问题:

#!/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;
4

2 回答 2

1

根据文档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;
于 2011-02-26T16:19:35.873 回答
1

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

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

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

于 2015-06-15T16:35:58.933 回答