缺少提交的 Perl DBIx::Class 个事务

Perl DBIx::Class transactions with missing commit

我为 Perl DBIx::Class 模块的不一致行为而苦恼。我写了一个简单的纯 Perl class,它定义了 class 成员 'schema',它只是对一个 pre initialized/connected DBIx::Class::Schema 对象的引用以及将一些数据添加到数据库的方法:

sub new {
    my $class = shift;
    my $params;
    if(1 == scalar @_ && 'HASH' eq ref($_[0])) {
        $params = shift;
    } else {
        my %params = @_;
        $params = \%params;
    }

    my $self = {
        schema => $params->{schema}
    };

    bless $self, $class;

    return $self;
}


sub addToQueue {
    my $self = shift;
    my $params;
    if(1 == scalar @_ && 'HASH' eq ref($_[0])) {
        $params = shift;
    } else {
        my %params = @_;
        $params = \%params;
    }
    
    #some parameter constraints checks
    ....
    
    $self->{schema}->txn_do(sub {
        $self->{schema}->resultset('SOME_QUEUE')->create($params);
    });

    # this row is necessary if this method is called from programs, which uses moose
    $self->{schema}->txn_commit();
 
    return;
}

如果我从一个 Perl(使用 Moose)程序调用方法 addToQueue,我必须添加代码行

self->{schema}->txn_commit();

真正触发数据库提交命令。如果我从另一个 Perl 程序(不使用 Moose)调用该方法,代码将失败并显示消息:

Use of uninitialized value $msg in substitution (s///) at /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm line 58. Use of uninitialized value $msg in concatenation (.) or string at /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm line 68. DBIx::Class::Storage::txn_commit(): Refusing to commit without a started transaction

如果我删除重复的提交命令,它适用于非 Moose 程序,但使用 Moose 的程序会忽略提交,创建的条目将不会写入数据库。

有人知道这些问题吗?

来自documentation for txn_do,

WARNING: If you are connected with AutoCommit => 0 the transaction is considered nested, and you will still need to call "txn_commit" to write your changes when appropriate. You will also want to connect with auto_savepoint => 1 to get partial rollback to work, if the storage driver for your database supports it.

Connecting with AutoCommit => 1 is recommended.

我怀疑你在需要额外的 txn_commit 时使用了 AutoCommit => 0

简短的回答是:您提交了两次交易。 txn_do 在没有抛出异常的情况下离开块时自动提交。 请 post 加载 Moose 的代码示例和来自 DBIC_TRACE=1 的日志,这表明没有触发任何提交。