Транзации, PDO и MSSQL

Василий М.

Новичок
PHP:
$dbh = new PDO("sqlsrv:Server=$hostname;Database=$dbname","$username","$pw");
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    $sql = 'select top 10 * from [med_Pay]';
    $stmt = $dbh->prepare($sql);
    $stmt->execute();

    $dbh->beginTransaction();

//     и не в этом дело даже....
//     while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
//             echo $row['id'] . "\n";  
//     }

    $dbh->commit();
  
} catch (Exception $e) {
    echo $e->getMessage();
    //$dbh->rollBack();
}
New transaction is not allowed because there are other threads running in the session.

куда копать? надо в транзацию обернуть как insert's, так и выборки.
 
Последнее редактирование:

Adelf

Administrator
Команда форума
а ты не хочешь ее начать ДО того как select выполнишь?
 

Василий М.

Новичок
а ты не хочешь ее начать ДО того как select выполнишь?
допустим, я этого НЕ хочу.
у меня на каждый цикл должна быть транзакция. не вставилась запись по какой-то - причине - откат и идем далее:

while ($row = $stmt2->fetch(PDO::FETCH_ASSOC))
// begin trans
// do...
// commit
 
Последнее редактирование:

Adelf

Administrator
Команда форума
Ну если я прав, то ты открыл курсор(это я терминами Оракл оперирую.. в мскуле может по другому называться), потом, не закрыв его, хочешь начать транзакцию. Что СУБД не очень хочет делать о чем и говорит.
Если хочешь делать как ты описал - получи все данные, закрой курсор и потом только открывай транзакцию.
 
Последнее редактирование:

Василий М.

Новичок
Поговорку про "вредно не хотеть" помнишь? Это как раз твой случай.
Выборка на транзакцию не влияет.
почему мой случай? Вот проблему реального кода я решил, но я не могу понять причину отказа данного примера. Там курсор не задействован ещё (по идее). Мне трудно понять внутренний механизм работы в данном примере.
 

Adelf

Administrator
Команда форума
$stmt->execute(); - вот здесь создается курсор. Некий проводник данных между твоей программой и СУБД. Он должен создаться либо внутри транзакции, либо должен быть уничтожен до ее открытия. Нельзя трнзакцию создавать когда курсор открыт. Ибо создается ситуация когда он открыт в одной транзакции, а используется в другой.
 

Василий М.

Новичок
Получается, "уничтожение" курсора - это прогон по результирующему набору. Так и есть:

PHP:
try {
  $sql = 'select top 10 * from [med_Pay]';
  $stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
  $stmt->execute();

  // Не сработает - не прошел через весь результирующий ряд
  // $stmt->fetchColumn();
 
  //  Так будет правильно
  while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {}

  $dbh->beginTransaction();
 
  $dbh->commit();
 
} catch (Exception $e) {
  echo $e->getMessage();
  $dbh->rollBack();
}
 
Последнее редактирование:

Adelf

Administrator
Команда форума
обычно там есть явное закрытие.. типа close. Но, наверно оно может и само закрывать после последней строки...
 

AnrDaemon

Продвинутый новичок
Я не понимаю, зачем ты так страдаешь?
Включи транзакцию до начала блока, с которым ты работаешь.
Либо используй fetchAll() уже.
 
Сверху