SELECT проблемы с Doctrine и MS SQL 2008

Мы написали приложение с использованием Doctrine2, которое прекрасно работает с базой данных MySQL или Postgres.

Теперь мы подключили приложение к базе данных SQL Server 2008, используя драйвер PDO DBLib, который использует реализацию FreeTDS для TDS (протокола Tabular DataStream), который используется SQL Server и Sybase.

Начальное создание схемы, транзакции и INSERT в таблицах работают нормально... после некоторой настройки Doctrine SQLServerPlatform и нашего пакета драйверов MSSQL.

Но при выборе данных мы сталкиваемся со следующей ошибкой:

General error: 20019 Attempt to initiate a new Adaptive Server operation with results pending

После долгих поисков я нашел эту деталь в FAQ FreeTDS:

Если вы привыкли программировать с другими серверами баз данных, вы можете быть удивлены, впервые столкнувшись с этим аспектом протокола TDS. [...]

Сервер требует, чтобы клиент либо прочитал все результаты запроса, либо указал, что дальнейшие строки не нужны, т. е. выдал отмену. Пока не произойдет одно из этих двух событий, сервер не будет принимать новые запросы по этому соединению. Он будет жаловаться на «ожидающие результаты».

Таким образом, причиной сообщения об ошибке является то, что по какой-то причине Doctrine (DBAL->PDO->FreeTDS) не прочитала все строки результата из буфера соединения, а сервер/библиотека не позволяет приложению выдать новый exec()/execute(), пока не будут прочитаны все строки.

  • Правильно ли я понимаю, что $doctrinequery->getResults() извлекает все результаты перед возвратом?
  • Правильно ли я понимаю, что $entity->getLinkedEntity() (т.е. $user->getGroupNames()) извлекает все результаты перед возвратом?
  • Как бы вы решили, где именно проблема?
    Стэктрейсы нам совсем не помогают, а кодовая база уже выросла.
  • Кто-нибудь еще уже имел эту проблему и может поделиться некоторыми идеями?
  • Есть ли альтернатива, которую мы можем использовать для подключения Doctrine к MSSQL, которая не страдает этой проблемой?

person Kaii    schedule 08.11.2012    source источник


Ответы (1)


У меня были аналогичные проблемы с PDO Driver DBLib и транзакциями. Я исправил это так:

$this->_db->beginTransaction();

$st = $this->_db->prepare("StoredProcedure ?");
$st->execute(array($data));
$results= $st->fetchAll();
$st->closeCursor();

// more stuff

$this->_db->commit();

closeCursor() решил мою проблему: http://php.net/manual/en/pdostatement.closecursor.php

person ibram    schedule 16.10.2013