DBM::Deep:事务问题

发布于 2024-10-19 02:51:06 字数 807 浏览 1 评论 0原文

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

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

I've never done transactions (in terms of programming), therefore I don't know if there is something wrong with my script or something else:

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

Output:

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

Part of comment:

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

春庭雪 2024-10-26 02:51:06

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

问题是 num_txns 仅在创建文件时设置。 (这是因为 DBM 文件在磁​​盘上的布局方式不同。)创建 DBM 文件后,将从文件中读取 num_txns 值,并在调用 时忽略该值。新的()。因此,一旦您更改了调用以指定 num_txns,除非您还使用了新的 DBM 文件,否则它不会有任何帮助。

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

Sorry about taking so long to answer this question - I only just found it a few days ago. (I'm the maintainer of DBM::Deep.)

The issue is that num_txns is only set when the file is created. (This is because of how the DBM file is laid out on disk.) Once you've created a DBM file, then the num_txns value is read from the file and ignored in the call to new(). So, once you changed your invocation to specify num_txns, it wouldn't help unless you also used a new DBM file.

While I cannot change this behavior without significantly changing how the DBM file structure works (which may be a good idea, but is a huge thing to do), you should have been warned and there should have been better documentation. I have opened https://github.com/robkinyon/dbm-deep/issues/12 to track this problem and the fix(es) for it.

云醉月微眠 2024-10-26 02:51:06

根据 文档 < code>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;

或 一些黑魔法的事情,你可以保持面向对象的风格

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;

Accoring to the documentation the rollback command ends the transaction.

rollback() This discards the changes
done within the transaction to the
mainline and ends the transaction.

Therefore you need to start a new transaction after a rollback.

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

or you could do something like

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;

or with a little black magic, you can keep the OO style

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文