Дескриптор базы данных DBI с AutoCommit, установленным на 0, не возвращает правильные данные с помощью SELECT?

Это сложно объяснить (и очень странно) , так что терпи меня. Я объясню проблему и ее исправление, но я хотел бы посмотреть, сможет ли кто-нибудь объяснить, почему он работает именно так:)

У меня есть веб-приложение, использующее 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).

11
задан sentinel 17 October 2010 в 06:22
поделиться