асинхронные запросы с MySQL / Perl DBI - PullRequest
1 голос
/ 17 июля 2011

Возможно, название моего вопроса вводит в заблуждение, но здесь идет -

Я испытываю прототип приложения, которое включает три веб-приложения на базе MySQL / Perl Dancer .

Пользователь переходит к приложению A, которое обслуживает базовый слой карт Google. Когда документ готов, приложение A выполняет три вызова jQuery ajax - два для приложения B, вот так

    http://app_B/points.json
    http://app_B/polys.json

и одно приложение C

    http://app_C/polys.json

Приложения B и C запрашивают базу данных MySQL через DBI и обслуживают json-пакеты точек и полисов, которые отображаются в браузере пользователя.

Все три приложения передаются через Apache в Perl Starman, запущенный через plackup, который запускается примерно так

    $ plackup -E production -s Starman -w 10 -p 5000 path/to/app_A/app.pl
    $ plackup -E production -s Starman -w 10 -p 5001 path/to/app_B/app.pl
    $ plackup -E production -s Starman -w 10 -p 5002 path/to/app_C/app.pl

Время от времени я начинаю получать сообщения об ошибках из приложений, вызываемых через Ajax. Начальные симптомы были

    {"error":"Warning caught during route 
     execution: DBD::mysql::st fetchall_arrayref 
     failed: fetch() without execute() at 
     <path/to/app_B/app.pm> line 79.\n"}

Оскорбительные строки:

    71> my $sql = qq{
    72>     ..
    73>
    74>
    75> };
    76> 
    77> my $sth = $dbh->prepare($sql);
    78> $sth->execute();
    79> my $res = $sth->fetchall_arrayref({});

Это странно ... как выполнить () не может быть выше? Perl не имеет привычки перепрыгивать через строки, не так ли? Итак, я включил DBI_TRACE

    $DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 

10 -a bin / app.pl

И, вот что выдалось мне потенциальным преступником в файле журнала

    > Handle is not in asynchronous mode error 2000 recorded: Handle is 
    > not in asynchronous mode
    >    !! ERROR: 2000 CLEARED by call to fetch method

Что происходит? Как правило, приложение А не работает, потому что другие приложения не возвращают данные «надежно» - я помещаю это в кавычки, потому что они иногда работают правильно, поэтому я знаю, что у меня нет логических или синтаксических ошибок в моем коде. У меня есть какая-то внутренняя ошибка сантехники.

На DBD :: mysql я нашел следующее об ASYNCHRONOUS_QUERIES и мне интересно, является ли это причиной и решением моей проблемы. По сути, если я хочу async запросов, я должен добавить {async => 1} к моему $dbh-prepare(). Кроме того, я не уверен, хочу ли я асинхронный истина или ложь. Я попробовал это, это, и это, кажется, не помогает.

Мне бы очень хотелось узнать, что здесь происходит, и как правильно решить эту проблему.

1 Ответ

4 голосов
/ 17 июля 2011

Как вы управляете дескрипторами вашей базы данных?Если вы открываете соединение до того, как starman разветвляет ваш код, то несколько детей могут пытаться использовать один дескриптор базы данных и сбивают с толку MySQL.Вы можете решить эту проблему, всегда запуская DBI->connect в ваших методах, которые обращаются к базе данных, но это может быть неэффективно.Многие люди переключаются на какой-то пул соединений, но у меня нет прямого опыта ни с одним из них.

...