2011-07-17 133 views
1

這可能是我的問題標題是誤導性的,但在這裏不用 -與異步查詢的MySQL/Perl的DBI

我想了一個原型應用程序,它涉及到三個的MySQL/Perl Dancer供電的網絡應用程序。

用戶轉到提供Google地圖基礎圖層的應用程序A。在文件準備好,應用一提出了三個jQuery的AJAX調用 - 兩到應用B像這樣

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

和一個附錄C

http://app_C/polys.json 

應用B和C查詢通過DBI的MySQL數據庫,以及提供在用戶瀏覽器中渲染的json數據包點和多邊形。

所有這三個應用程序都通過Apache代理到Perl的接龍運行通過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斌/ 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 

什麼正在進行?基本上,因爲應用程序A是非功能性的,因爲其他應用程序不會「可靠地」返回數據 - 我將它放在引號中,因爲它們偶爾會正常工作,所以我知道我沒有任何邏輯或語法錯誤在我的代碼中。我有一些內在的管道錯誤。

我確實在DBD::mysql about ASYNCHRONOUS_QUERIES上找到了以下內容,並且想知道這是否是我的問題的原因和解決方案。本質上,如果我想要async查詢,我必須將{async => 1}添加到我的$dbh-prepare()。除此之外,我不確定是否需要異步真或假。我試過了,它似乎沒有幫助。

我很想知道這裏發生了什麼,以及解決這個問題的正確方法是什麼。

回答

3

你如何管理你的數據庫句柄?如果您在starman之前開放連接,則會分叉您的代碼,那麼多個孩子可能會嘗試共享一個數據庫句柄並令MySQL感到困惑。您可以通過在與數據庫交談的方法中始終運行DBI->connect來解決此問題,但這可能效率低下。許多人轉而使用某種連接池,但我沒有任何直接經驗。

+0

我認爲這是原因,你已經打到了頭上。我確實在方法之外創建了$ dbh。我已經將它移到了方法調用中,並且應用程序似乎保持不變。仍在測試,但真的非常感謝你的洞察力。 – punkish