Это сложно объяснить (и очень странно) , так что терпи меня. Я объясню проблему и ее исправление, но я хотел бы посмотреть, сможет ли кто-нибудь объяснить, почему он работает именно так:)
У меня есть веб-приложение, использующее mod_perl. Он использует базу данных MySQL, и я регулярно записываю данные в базу данных. Он модульный, поэтому у него также есть собственный тип модуля «база данных», в котором я обрабатываю соединения, обновления и т. Д. Подпрограмма database :: db_connect () используется для подключения к базе данных, и AutoCommit
установлен в 0.
Я сделал другое приложение Perl (автономный демон), которое периодически извлекает данные из базы данных и выполняет различные задачи в зависимости от того, какие данные возвращаются. Я включаю в него модуль database.pm, поэтому мне не нужно все переписывать / дублировать.
Проблема, с которой я сталкиваюсь:
Приложение подключается к базе данных при запуске, а затем зацикливается на бесконечности, извлекая данные из базу данных каждые X секунд. Однако, если данные в базе данных обновляются, мое приложение по-прежнему возвращает «старые» данные, которые я получил при первоначальном подключении / запросе к базе данных.
Например - у меня есть 3 строки и столбец «Имя» имеет значения 'a', 'b' и 'c' - для каждой записи. Если я обновлю одну из строк (используя клиент mysql из командной строки, например) и измените Имя с 'c' на 'x', мой автономный демон не получит эти данные - он все равно получит a / b / c, возвращенный MySQL. Я захватил трафик db с помощью tcpdump, и я определенно мог видеть, что MySQL действительно возвращает эти данные. Я также пробовал использовать SQL_NO_CACHE с SELECT (поскольку я не был уверен, что происходит), но это тоже не помогло.
Затем я изменил строку подключения к БД в моем автономном демоне и установил AutoCommit
на 1. Внезапно приложение начало получать правильные данные.
Я озадачен, потому что я думал, что AutoCommit влияет только на типы операторов INSERT / UPDATE и не влияет на оператор SELECT. Но, похоже, это так, и я не понимаю почему.
Кто-нибудь знает, почему оператор SELECT не возвращает 'обновлено' строк из базы данных, когда AutoCommit
установлен в 0, и почему он будет возвращать обновленные строки, когда AutoCommit
установлен в 1?
Вот упрощенная (удаленная проверка ошибок, и т. д.) код, который я использую в автономном демоне и который не возвращает обновленные строки.
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Data::Dumper;
$|=1;
my $dsn = "dbi:mysql:database=mp;mysql_read_default_file=/etc/mysql/database.cnf";
my $dbh = DBI->connect($dsn, undef, undef, {RaiseError => 0, AutoCommit => 0});
$dbh->{mysql_enable_utf8} = 1;
while(1)
{
my $sql = "SELECT * FROM queue";
my $stb = $dbh->prepare($sql);
my $ret_hashref = $dbh->selectall_hashref($sql, "ID");
print Dumper($ret_hashref);
sleep(30);
}
exit;
Изменение AutoCommit
на 1 исправляет это. Почему?
Спасибо :)
PS: Не уверен, кого это волнует, но версия DBI - 1.613, DBD :: mysql - 4.017, perl - 5.10.1 (в Ubuntu 10.04).