2017-08-18 99 views
-1

在我的代碼中,我使用database->last_insert_id(undef,undef,undef,"id");來獲取自動增量主鍵。這工作99.99%的時間。但偶爾會返回0值。 在這種情況下,使用與INSERT語句的值類似的WHERE子句運行select將顯示insert成功。指示last_insert_id方法未能獲得正確的數據。Perl5 DBI Mysql:獲取last_insert_id的可靠方法

這是一個已知的問題已知的修復?或者我應該跟蹤每次調用last_insert_id檢查,看看它是否爲零,如果是的話,選擇語句檢索正確的ID值?

我的MySQL版本是 的MySQL版本14.14 DISTRIB 19年5月7日,對於Linux下(x86_64)

EDIT1:添加實際的失敗代碼。

use Dancer2::Plugin::Database; 
<Rest of the code to create the insert parameter> 
eval{ 
    database->quick_insert("build",$job); 
    $job->{idbuild}=database->last_insert_id(undef,undef,undef,"idbuild"); 
    if ($job->{idbuild}==0){ 
     my $build=database->quick_select("build",$job); 
     $job->{idbuild}=$build->{idbuild}; 
     } 
    }; 
debug ("=================Scheduler build Insert=======================*** ERROR :Got Error",[email protected]) if [email protected]; 

注意:我使用的是Dancer的數據庫插件。誰介紹說,

提供一種簡單的方式,通過 獲得連接DBI數據庫句柄簡單地調用您的應用程序Dancer2

返回一個舞者::插件::數據庫::核心內的數據庫關鍵字:處理對象,這是DBI的DBI :: db連接句柄對象的一個​​子類,因此它確實可以用DBI做的所有事情,但也增加了幾個 便利方法。有關這些的完整詳細信息,請參閱 Dancer :: Plugin :: Database :: Core :: Handle的文檔。

+1

你知道那個返回數據庫句柄的最後一個插入,對吧?插入後立即執行,還是先做其他事情?連接是否會超時(或死亡),您的客戶正在獲取新的句柄?我很確定last_insert_id沒有一些普遍存在的問題,所以你的代碼可能會有些怪異。展示下。 – ysth

+0

我已更新我的原始問題以添加失敗的代碼片段。 我在插入後立即調用last_insert_id。 我已經將'RaiseError'和'PrintError'選項傳遞給了我的連接,但是我沒有看到此故障的任何錯誤消息。 – vijayvithal

回答

0

我從來沒有聽說過這種類型的問題,但我懷疑你的結束筆記可能是關鍵。 Dancer :: Plugin :: Database在幕後爲您透明地管理數據庫句柄。這可能非常方便......但這也意味着您可以隨時使用一個dbh來改變使用不同的dbh。來自the docs

調用database將返回一個連接的數據庫句柄;第一次調用它時,插件將建立到數據庫的連接,並返回對DBI對象的引用。在後續調用中,將返回相同的DBI連接對象,除非發現它不再可用(連接已斷開),在這種情況下將獲得新的連接。

(重點煤礦)

而且,正如YSTH已經對你的問題的意見中指出,last_insert_id是處理特定的,這表明,當你得到0,這可能是由於處理你的變化。

但是有希望!繼續在D :: P :: DB文檔中,有一個database_connection_lost鉤子可用,它在數據庫連接消失並接收到作爲參數的失效句柄時調用,這將允許您在鉤子的回調中檢查並記錄last_insert_id子。這可以爲您提供一種方式讓您在沒有附加查詢的情況下獲取該標識,儘管您首先必須設法將回調中的信息從主要處理代碼中獲取。

另一個可能的解決方案當然是不使用D :: P :: DB並自己管理數據庫連接,以便您可以直接控制何時創建新連接。

+0

從doc引用。 >確保數據庫句柄仍然連接且有效。如果句柄最後一次詢問的時間超過connection_check_threshold秒,它將檢查連接是否仍然存活,如果DBD驅動程序支持,則使用$ dbh-> ping方法或對數據庫執行簡單的無操作查詢如果不。如果連接消失,將獲得並返回新的連接。這可以避免連接數據庫的長時間運行的腳本可能會消失的任何問題。 – vijayvithal

+0

在上面的代碼中,插入後面緊跟着last_insert_id()...因此,連接丟失時存在足夠大的間隔的可能性非常低... 我會嘗試寫一個鉤子來打印出來一個消息,每當連接丟失,並看看它是否是這個問題的根源... – vijayvithal

+0

@vijayvithal - 我同意這似乎不太可能,但這是唯一的潛在的解釋我(或者,似乎,其他人)可以上來用。我期待着聽到你的鉤子實驗是否證實或否認了我的理論。 –

相關問題