子プロセスで Apache::DBI を使用すると問題が発生します。問題は、Apache::DBI がそれを使用するすべてのプロセスに対して単一のハンドルを提供することです。
DBD::mysql::db selectall_arrayref が失敗しました: コマンドが同期していません。/usr/local/www/apache22/data/test-fork.cgi 20 行目でこのコマンドを実行することはできません。
次のエラーを理解したので、Apache::DBI はすべてのプロセスで再接続するため、再接続は役に立ちません。
サーバーで内部エラーが発生し、リクエストを完了できませんでした。
エラー メッセージ: DBD ドライバーは、/usr/local/lib/perl5/site_perl/5.8.9/Apache/DBI.pm 行 283 で AutoCommit 属性を実装していません。
元のコードは次のとおりです。
use Data::Dumper 'Dumper';
use DBI ();
my $dbh = DBI->connect($dsn, $username, $password, {
RaiseError => 1,
PrintError => 0,
});
my $file = "/tmp/test-fork.tmp";
my $pid = fork;
defined $pid or die "fork: $!";
if ($pid) {
my $rows = eval { $dbh->selectall_arrayref('SELECT SLEEP(1)') };
print "Content-Type: text/plain\n\n";
print $rows ? "parent: " . Dumper($rows) : $@;
}
else {
my $rows = eval { $dbh->selectall_arrayref('SELECT SLEEP(1)') };
open FH, '>', $file or die "$file: $!";
print FH $rows ? "child: " . Dumper($rows) : $@;
close FH;
}
再接続に使用したコード:
...
else {
$dbh->disconnect;
$dbh = DBI->connect($dsn, $username, $password, $attrs);
my $rows = eval { $dbh->selectall_arrayref('SELECT SLEEP(1)') };
open FH, '>', $file or die "$file: $!";
print FH $rows ? "child: " . Dumper($rows) : $@;
close FH;
}
fork で Apache::DBI を安全に使用する方法はありますか? おそらく新しい接続を作成する方法はありますか?