Обычно подключение к серверу остается открытым на протяжении работы сценария и завершается автоматически после завершения работы сценария. При необходимости можно завершить соединение раньше или просто завершить соединение явным образом. Такая потребность может возникнуть, если возможность своевременного отключения от сервера позволяет снизить нагрузку на сервер MySQL. Для разрыва соединения можно воспользоваться методом disconnect() , указав там дескриптор базы данных.
Листинг 20.10.
$dbh->disconnect();
Если сценарий запустил транзакцию с использованием метода begin_work() или зна­чения 'AutoCommit' =>0 в вызове connect() , перед тем как вызвать метод discon-nect(), необходимо вызвать методы commit() или rollback(). Рассмотрим пример.
Листинг 20.11.
#! /usr /bin/perl
# загрузить модуль use DBI();
# присвоение значений переменным транзакции!
# предположим, что это получено через стандартный ввод $name = "Ian T";
$nat = "IN";
$dept = "HumanResources"; $pbasic = 55000; $pbonus = 7500;
# соединить
my $dbh = DBI-
>connect("DBI:mysql:database=master;host=l92.168.0.241","root", "secret",
'RaiseError'=> 1, 'AutoCommit'=> OJ);
# транзакция помещается в блок eval{}
# поэтому в случае ошибки можно будет сделать откат eval
{
# добавить запись с данными о работнике
$dbh->do ("INSERT INTO employees (ename, enationality) VALUES C$name', '$nat')");
# получить идентификатор автосчетчика для добавленной записи $id = $dbh->{'mysql_insertid'};
# добавить данные об отделе, в котором работает работник
$dbh->do("INSERT INTO
departments(eid,dept)VALUES('$id,,,$dept')");
# добавить данные о заработной плате
$dbh->do("INSERT INTO payroll (eid, pbasic, pbonus) VALUES
(,$id,,,$pbasic,,,$pbonus')"); 
# нет ошибок? Занести в базу данных! $dbh->commit ();
};
# в случае ошибки - откат!
if ($@)
{
print "Транзакция прервана: $@"; $dbh->rollback();
}
# очистить $dbh->disconnect();
Здесь транзакция включает добавление работника в базу данных, содержащую ин­формацию о работниках. Для этого данные добавляются в три разные таблицы. Первый шаг заключается в подключении к базе данных с помощью метода connect() . Обратите внимание на появление в методе connect() параметра AutoCommit. Как было указано в главе 12, "Транзакции", это информирует MySQL о необходимости отключения авто­матического выполнения команд SQL и о включении всех запросов в единый блок тран­закции, который будет выполняться целиком.
После установления соединения, для вставки новых данных о работниках используются стандартные SQL-операторы INSERT. Эти операторы заключены в блок обработки исключительных ситуаций eval{... } . Суть в том, что при возникновении какой-либо ошибки, этот блок завершает свою работу и возвращает управление программе верхнего уровня. Ошибка, которая сохраняется в переменной Perl $@ (это сообщение об ошибке, сгенерированное блоком eval{... } ), приводит к немедленному откату - rollback() . При отсутствии ошибки, транзакция будет завершена методом commit() . Очевидно, что такой метод программирования будет работать только с таблицами, которые поддерживают работу с транзакциями, например, с таблицами типа InnoDB.
Оставляя все на потом
Альтернативой методу connect() является метод connect_cashed(), который со­храняет информацию об открытых соединениях с базой данных и в случае попытки открыть уже открытое соединение, возвращает объект дескриптора уже открытой базы данных (вместо того, чтобы сделать попытку повторно и открыть уже открытое соединение).
При работе с интерфейсом DBI необходимо быть предельно осторожным относительно открытых соединений с базой данных. Все базы данных имеют определенное ограничение на количество одновременно открытых соединений. Если максимальное количество параллельно работающих клиентов не задано, имеет смысл открыть нужное соединение и закрыть его сразу же, как только необходимость в нем отпала. Это делается во избежание ситуаций, когда сервер базы данных будет настолько перегружен, что он не сможет открыть ни одного нового соединения.
Для управления соединением можно воспользоваться дополнительными специали­зированными функциями, имеющимися в арсенале интерфейса DBI. Все они перечислены в табл. 20.1.