Находил в интернете очень много статей о том, как пользоваться функцией fork() или интерфейсов DBI, но ни разу не встречал статей о том, с какими проблемами сталкиваешься при одновременном использовании этих вещей. Хочу написать о том, с чем столкнулся я при их использовании.Я, в частности, при разработке приложения на Perl, использующем fork() и DBD::Pg, столкнулся со следующими проблемами.
Проблема 1: автоматически закрывается соединение с БД после уничтожения одного из дочерних процессов.
Данная проблема возникает из-за того, что Perl автоматически уничтожает переменные, ссылок на которые больше нет. Решение данной проблемы можно найти в описании модуля DBI в архиве CPAN. В частности, смотрите описание атрибута InactiveDestroy.
Итак, чтобы соединение не закрывалось автоматически, то необходимо присвоить этому атрибуту ложное значение – ноль, пустая строка или неопределенное значение. Но при этом необходимо не забывать, что будет хорошим тоном закрыть соединение в конце работы родительского процесса вручную или автоматически.
Можно использовать следующий алгоритм для автоматического закрытия соединения в родительском процессе.
my $dbh = DBD::SomeDriver->new();
$dbh->{InactiveDestroy} = undef; # Разрешаем автоматическое закрытие соединения
. . .
my $child = fork();
unless ($child) {
$dbh->{InactiveDestroy} = 1; # Запрещаем автоматическое закрытие соединения в дочернем процессе
. . .
}
. . .
Проблема 2: возникают ошибки типа ‘Statement is already prepared‘ в дочерних процессах
Данные ошибки возникают при использовании метода prepare() для подготовки SQL-запросов. Один из вариантов, которым я пользуюсь, является клонирование дескриптора БД.
Дополняя предыдущий пример, можно прийти к такому алгоритму.
my $dbh = DBD::SomeDriver->new();
$dbh->{InactiveDestroy} = undef; # Разрешаем автоматическое закрытие соединения
. . .
my $child = fork();
unless ($child) {
$dbh->clone(); # Создаем копию дескриптора БД
$dbh->{InactiveDestroy} = 1; # Запрещаем автоматическое закрытие соединения в дочернем процессе
. . .
}
. . .
Leave a Reply
You must be logged in to post a comment.
