2

トランザクション内のwithからストアドプロシージャを簡略化された形式で呼び出そうとしています。

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を使用しており、DBI 1.616がインストールされたCentosを実行しているAmazonクラウドインスタンスを使用しています。これは、両方で発生します。

これは機能する必要がありますか、それとも回避する方法がありますか?

ありがとう

4

2 に答える 2

2

明示的にトランザクションfinish()を実行する前に、すべての実行された準備済みプロシージャ CALLを明示的に確認してください。commit()例えば、

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

の典型的なセマンティクスを考えると、これはバグのように見えますfinish()。複数の結果セット、呼び出しmore_resultsなどは問題ではありませんでした。

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

于 2012-04-03T21:15:52.897 に答える
1

を使用している場合はAutoCommit => 0、必要ありませんbegin_work()。あなたcommit()またはまで、すべてがトランザクション内にありますrollback()。その後、新しいトランザクションが開始されます。

実際には、 で接続する必要があります。 が 0 の場合にRaiseError => 1エラーが発生するはずです。細かいドキュメントから:begin_work()AutoCommit

begin_work が呼び出されたときに AutoCommit がすでにオフになっている場合は、エラーを返す以外は何もしません。ドライバーがトランザクションをサポートしていない場合、begin_work が AutoCommit をオフに設定しようとすると、ドライバーは致命的なエラーを引き起こします。

また、どのバージョンDBD::mysqlを使用していますか?最新バージョンは実装していると思いますAutoCommit

于 2011-06-23T16:47:40.437 に答える