preload
Фев 16

Находил в интернете очень много статей о том, как пользоваться функцией 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.