2016-08-01 63 views
1

我有一個Perl腳本,它使用不同的連接驅動程序連接到許多數據庫。如何從所有數據庫連接字符串斷開連接

有沒有什麼辦法可以在最後斷開一個單獨的斷開連接功能來斷開連接?

例子:

connection 1: $dbh->oracle; 
connection 2: $dbh->sql 

我可以有兩個數據庫的共同斷開連接字符串?

+3

當語句句柄超出範圍時,DBI將爲您隱式斷開連接。 – simbabque

+0

@simbabque:我得到的錯誤是:由於DESTROY沒有明確的斷開連接()發出rollback().....我使用單獨的斷開連接功能來防止這種情況,但使用單個斷開連接功能對於所有字符串。 – Husk01inJun

回答

3

你可以使用visit_handles from DBI自己實現。

use strict; 
use warnings; 
use DBI; 

my $dbh = DBI->connect('DBI:mysql:database=test;host=localhost', 'root', 'pw'); 
my $dbh2 = DBI->connect('DBI:mysql:database=test;host=localhost', 'root', 'pw'); 

DBI->visit_handles(
    sub { 
     my ($driver_handle, $info) = @_; 

     if ($driver_handle->{Type} eq 'db') { 
      # clean up transaction or simply disconnect for each handle 
      $driver_handle->disconnect; 
     } 

     return 1; 
    } 
); 

傳遞給visit_handles代碼參考將呼籲每個驅動程序句柄。如果它返回一個真值,它將隨後用相同的代碼引用調用visit_child_handles。這樣,你可以匹配哪些是數據庫句柄(db),並明確斷開它們。

由於Borodin states in their answer您需要在斷開連接之前處理完成一半的事務。該解決方案僅爲您提供了從一個位置獲取所有連接手柄的方法。

+0

不錯。我不知道'visit_handles'。但是,顯式調用'disconnect'將產生與perl破壞程序時執行的隱式斷開相同的警告,並且您需要對每個具有打開事務的句柄執行「回滾」或「提交」。 – Borodin

+0

@borodin hmm true。當我回到我的電腦時我會編輯。 – simbabque

+0

@Borodin我不知道這一點,謝謝你的信息。我試圖連接不同的驅動程序,如oracle,postgres和mysql。只是懷疑這是否會起作用,當我回到我的電腦時會嘗試 – Husk01inJun

2

每個數據庫連接將被表示爲一個單獨的數據庫處理$dbh

顯然,您可以編寫一個從所有連接的數據庫處理器斷開,只要你連接的數據庫列表中的子程序始終是相同的

我不知道爲什麼你在注視連接字符串。據推測你的意思是你在撥打DBI->connect時使用的DSN(數據源名稱)?它們僅僅是參數的連接操作和數據庫處理不能在事後被鑑定出它的原始DSN

Issuing rollback() due to DESTROY without explicit disconnect() 

這意味着,你正在使用的交易。最好的方法是自己撥打rollbackcommit來結束交易。這是一個壞主意,留下交易時打開程序終止,你所依賴的數據庫驅動程序

documentation for DBI::disconnect的默認行爲,一般來講這個

,如果你想被提交改變或當你斷開連接時回滾,那麼你應該在斷開連接之前明確地調用「commit」或「rollback」。

你也將得到同樣的警告,如果你調用disconnect而交易仍然是開放的,所以commitrollback絕對是正確的方法

它是好的,讓Perl的破壞序列implcitly斷開所有數據庫句柄,只要沒有事務處於打開狀態