2016-08-01 2 views
1

У меня есть скрипт Perl, который подключается ко многим базам данных с использованием разных драйверов соединений.Как отключить все строки подключения базы данных

Есть ли способ написать одну функцию разъединения в конце, чтобы отключить, если есть какая-либо активная сессия?

Пример:

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

Могу ли я иметь общую строку отключения для обеих баз данных?

+3

DBI будет отключен неявно для вас, когда дескриптор инструкции выходит из области видимости. – simbabque

+0

@simbabque: я получаю ошибку как: выдача отката() из-за DESTROY без явного отключения() ..... Я использую отдельную функцию разъединения, чтобы предотвратить это, но было бы здорово использовать одну функцию разъединения для всех строки. – 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

Очевидно, вы могли бы написать подпрограмму, которая разъединяет от всех подключенных ручек базы данных, до тех пор, как ваш список подключенных баз данных всегда одинакова

Я не уверен, почему вы фиксируете строки подключения. Предположительно, вы имеете в виду DSN (имена источников данных), которые вы использовали при вызове DBI->connect? Они просто параметры для операции соединения и дескриптор базы данных не может быть идентифицирован после факта из первоначального источника данных

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

Это означает, что вы используете транзакции. Лучшим способом было бы позвонить rollback или commit самостоятельно, чтобы завершить транзакцию. Это плохая идея, чтобы оставить открытой транзакции, когда программа завершается, как вы полагаетесь на поведение по умолчанию драйвера базы данных

documentation for DBI::disconnect говорит этот

Вообще, если вы хотите, чтобы ваши изменения должны быть совершены или откатываясь при отключении, вы должны явно называть «commit» или «rollback» перед отключением.

Вы также получите такое же предупреждение, если вы звоните disconnect пока транзакция остается открытой, так commit или rollback, безусловно, правильный метод

Это прекрасно, чтобы последовательность разрушения в Perl implcitly отключить все базы данных обрабатывается до тех пор, пока транзакции не остаются открытыми в то время

Смежные вопросы