2009-07-05 8 views
12

Używam następującego kodu do transakcji w Zend Framework, ale funkcja rollback nie działa (dane są wstawiane do bazy danych przez insertSome ($ data)). Co jest nie tak?Nie można wycofać transakcji w Zend Framework

  $db->beginTransaction(); 
      try{ 
       $model->insertSome($data); 
       $model->insertAll($data2); //this line cannot be run and the whole transaction should be rolled back. 
       $db->commit(); 
      } catch (Exception $e) { 
       $db->rollBack(); 
       echo $e->getMessage(); 
      } 
+7

Czy Twój DB jest przez przypadek MySQL przy użyciu tabel MyISAM? Nie obsługują transakcji. Jeśli chcesz obsługi transakcji, musisz użyć tabel InnoDB. – nos

+0

Tak, używam tabel MyISAM. Zmieniłem tabele InnoDB i to działa. Dzięki. – Billy

Odpowiedz

20

Nie możemy na to pytanie z listy „bez odpowiedzi” pytania na StackOverflow, chyba że istnieje co najmniej jedna odpowiedź z upvote. Powtarzam więc rozwiązanie, które omówiliście powyżej w komentarzach.

@nos proponuje:

Czy Twój DB przypadkiem MySQL przy użyciu tabel MyISAM? Nie obsługują transakcji . Aby uzyskać transakcję , należy użyć tabel InnoDB .

@Billy odpowiada:

Tak, używam tabel MyISAM. Zmieniłem tabele InnoDB i działa. Dzięki.

(mam zaznaczone to jako odpowiedź Wiki, więc nie dostać żadnych punktów od niego.)

2

Jeśli mój stolik był InnoDB, (patrząc od SHOW CREATE TABLE xxx) i moja transakcja nie cofnął się, co byś zasugerował?

CREATE TABLE `EarningCode` (
`ID` int(11) NOT NULL auto_increment, 
`EarningCode` varchar(16) collate utf8_unicode_ci NOT NULL, 
`Description` varchar(255) collate utf8_unicode_ci NOT NULL, 
`DateEffective` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
`Rate` float NOT NULL, 
PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=1239 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

To część testach jednostkowych: Mam skonfigurować metodę, która uruchamia transation:

protected function setUp() 
{ 
    global $db; 

    $db->beginTransaction(); 

    // Insert this tested object into db. 
} 

i sposób zburzyć, które powinny zapewnić, że rząd nie jest włożona do dB (każdy czas, w którym test jest uruchamiany w tej klasie testowej, wykonuje parę setUp/tearDown, więc nie chcę duplikatów, które wypełniają moją tabelę db).

protected function tearDown() 
{ 
    global $db; 

    $db->rollBack(); 
} 

Sprawdziłem co SQL jest wykonywany, a widzę, że AUTOCOMMIT jest ustawiona na false, gdy transakcja jest uruchamiany i przełącza się prawdą po wycofaniu, ale rząd pozostaje włożona.

0

Twój kod jest OK.

Sprawdź opcje stołu. Potrzebujesz użyć silnika Transacctional z InnoDb

2

Do wykorzystania w przyszłości, aby dowiedzieć się, czy to naprawdę wyjątek DB, użyj zamiast tego Zend_Db_Exception.

} catch (Zend_Db_Exception $e) { 
    $db->rollBack(); 
    echo $e->getMessage(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
}