вижу несколько вариантов:
- Явно закройте ваши ручки БД при разветвлении и откройте их при необходимости.
например:.
my $dbh = DBI->connect(...);
my $pid = fork;
defined $pid or die "fork: $!";
if ($pid) {
# parent...
}
else {
# child...
undef $dbh;
Эту задачу можно упростить, храня $dbh
в объекте и передавая этот объект по мере необходимости в части вашей системы. Объект будет отвечать за повторное открытие $ dbh по мере необходимости, поэтому остальная часть приложения не должна заботиться о деталях. Сохраняйте код инкапсулированным и хорошо отделенным от других частей системы.
Я использую DBIx :: Connector в моей системе внутри объекта Moose, который использует делегирование метода для предоставления dbh. Приложение просто делает:
my $dbh = $db_dbj->dbh;
my $sth = $dbh->prepare(...);
# more boring DBI code here
... И DBH повторно подключается / восстанавливается по мере необходимости, невидимо.
Кроме того, вы должны быть очень осторожны с использованием простых файловых дескрипторов в многопроцессорной среде. Вы могли бы очень легко забить ваши данные. open (my $fh, $file) or die "Cannot open $file: $!"
намного безопаснее.
Я также немного нервничаю, когда вижу, что вы используете блоки eval {}
без проверки содержимого $@
. Вы просто маскируете ошибки, а не имеете дело с ними, поэтому может происходить больше вещей, чем вы знаете. Проверьте значения результата (или лучше, используйте явный модуль обработки исключений, такой как Try :: Tiny . Use use strict; use warnings;
.
PS. Я только что заметил, что вы явно включаете DBI
в свой код. Не делай этого. Если вы используете Apache :: DBI в вашем файле startup_modperl.pl (или как вы называете файл начальной загрузки), вам никогда не придется включать сам DBI. Я не могу сказать наверняка, но я не был бы уверен, что нужный пакет вызывается (прошло некоторое время с тех пор, как я посмотрел на внутренности Apache :: DBI; хотя он может позаботиться об этом за вас).