问题描述
我为Perl DBIx :: Class模块的不一致行为而苦恼。我编写了一个简单的纯Perl类,该类定义了类成员'schema',它只是对预初始化/连接的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)中调用该方法,则代码将失败,并显示以下消息:
使用未初始化的值$ msg代替(s ///) /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm第58行。 串联(。)中的未初始化值$ msg或位于的字符串 /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm第68行。 DBIx :: Class :: Storage :: txn_commit():拒绝提交而无需 开始交易
如果删除重复的commit命令,则该命令适用于非Moose程序,但是使用Moose的程序会忽略该提交,并且创建的条目不会写入数据库。
有人知道这些问题吗?
解决方法
警告:如果您与
AutoCommit => 0
连接,则该事务被视为嵌套的,并且您仍然需要在适当的时候调用“ txn_commit”来编写您的更改。如果您数据库的存储驱动程序支持,则还需要与auto_savepoint => 1
连接以使部分回滚工作。建议连接
AutoCommit => 1
。
我怀疑您在需要额外的AutoCommit => 0
时正在使用txn_commit
。
简短的答案是:您要两次提交事务。
txn_do
在没有引发异常时离开该块时会自动提交。
请发布一个代码示例,该示例加载Moose以及DBIC_TRACE = 1中的日志,该日志显示未触发提交。