【问题标题】:DBI begin_work doesn't work with stored procedure callsDBI begin_work 不适用于存储过程调用
【发布时间】:2011-09-21 05:48:12
【问题描述】:

我正在尝试以简化形式从事务中调用存储过程:

my $dbh= DBI->connect(............  );  

my $sth = $dbh->prepare("call sp_get_workitems (1,1)");
$dbh->begin_work  or die $dbh->errstr;
$sth->execute();
my ($result)= $sth->fetchrow_array();

$dbh->commit;

这会产生以下错误:

DBD driver has not implemented the AutoCommit attribute

如果我将 begin_work 语句替换为 $dbh->{'AutoCommit'} = 0;(在准备之前或之后),我会收到以下错误:

DBD::mysql::db commit failed: Commands out of sync; you can't run this command now

如果我用一个简单的 select 语句替换存储过程调用,一切正常。

存储过程包括许多更新,并以 select 语句结束。 当然,如果我可以在过程中处理事务会更容易,如果发生回滚,我需要执行一些 perl 代码。

我在 Windows 7 上使用 ActivePerl 和一个运行 Centos 并安装了 DBI 1.616 的亚马逊云实例,这两种情况都会发生。

这应该可行还是有解决办法?

谢谢

【问题讨论】:

    标签: mysql perl stored-procedures dbi autocommit


    【解决方案1】:

    确保在显式 commit() 事务之前显式地 finish() 每个执行的准备过程 CALL。例如,

    $sth->finish;
    $sth->commit();
    

    鉴于finish() 的典型语义,这对我来说似乎是一个错误。多个结果集,调用more_results等都没关系。

    DBD 1.616、DBD::mysql 4.020 和 MySQL 5.5.19。

    【讨论】:

    • 请注意:如果您使用的是准备好的语句,请不要忘记在提交或回滚之前在 PS 处理程序上调用 ->finish 方法。
    【解决方案2】:

    如果您使用的是AutoCommit => 0,则不需要begin_work()。在您commit()rollback() 之前,一切都在事务中。然后开始新的交易。

    实际上,您应该与RaiseError => 1 连接,因为当AutoCommit 为0 时,您应该在begin_work() 上收到错误消息。来自精美的文档:

    如果 AutoCommit 已关闭,则 begin_work 被调用然后它确实 除了返回错误之外什么都没有。如果 驱动程序不支持事务 然后当 begin_work 尝试设置 AutoCommit off 驱动会触发 致命错误。

    另外,您使用的是哪个版本的DBD::mysql?我认为最新版本确实实现了AutoCommit

    【讨论】:

    • 正如我所说,我用 autoCommit=>0 替换了 begin_work 语句,从未将它们一起使用,但是两者都不能与存储过程一起使用。我正在使用 DBD::mysql 4.019
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 2015-11-11
    • 1970-01-01
    • 2011-03-04
    • 2021-09-04
    • 2011-09-16
    • 1970-01-01
    • 2018-05-21
    相关资源
    最近更新 更多