Невозможно выполнить транзакцию возврата в Zend Framework
Я использую следующий код для транзакции в Zend Framework, но функция отката не работает (данные вставляются в базу данных посредством insertSome ($ data)).
Что не так?
$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();
}
Ответы
Ответ 1
Мы не можем получить этот вопрос из списка "неотвеченных" вопросов в StackOverflow, если нет хотя бы одного ответа с upvote. Поэтому я повторяю решение, о котором вы говорили выше, в комментариях.
@nos предлагает:
Является ли ваша БД какой-либо возможностью использовать MySQL Таблицы MyISAM? Они не поддерживают сделки. Вам нужно будет использовать InnoDB таблицы, если вы хотите совершить транзакцию поддержка.
@Billy отвечает:
Да, я использую таблицы MyISAM. Я изменился на таблицы InnoDB, и он работает. Спасибо.
(Я отметил это как ответ wiki сообщества, поэтому я не получаю от него никаких баллов.)
Ответ 2
Если моя таблица была InnoDB (видно из SHOW CREATE TABLE xxx
), и моя транзакция не отскакивала, что бы вы предложили?
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
Это часть тестов Unit: у меня есть метод настройки, который запускает трансацию:
protected function setUp()
{
global $db;
$db->beginTransaction();
// Insert this tested object into db.
}
и метод разрыва, который должен гарантировать, что строка не вставлена в db (каждый раз, когда тест выполняется в этом тестовом классе, он выполняет парную пару setUp/tearDown и поэтому я не хочу, чтобы дубликаты, которые заполняли моя таблица db).
protected function tearDown()
{
global $db;
$db->rollBack();
}
Я проверил, что SQL выполняется, и я вижу, что при запуске транзакции для autocommit установлено значение false и после откат переключается на true, но строка остается вставленной.
Ответ 3
Для будущего использования, чтобы узнать, действительно ли это исключение БД, вместо этого используйте Zend_Db_Exception.
} catch (Zend_Db_Exception $e) {
$db->rollBack();
echo $e->getMessage();
} catch (Exception $e) {
echo $e->getMessage();
}
Ответ 4
Ваш код в порядке.
Проверьте свою таблицу. Вам необходимо использовать Transacctional engine с InnoDb