Так вот, когда я пытаюсь начать транзакцию внутри exec(), то получаю ошибку PDO: "There is already an active transaction". Не может быть, чтобы нельзя было использовать вложенные транзакции. Но как это сделать? Пока не могу найти ответа на этот вопрос.
Объясняю, в чем смысл, и почему решение, которое предложил napeHeK, не подходит.
Например, есть ресурс, где размещаются статьи и комментарии к ним. В разных случаях могут удаляться либо только комментарии, либо статьи со всеми комментариями, к ним добавленными.
Я пишу отдельно функцию удаления коммента (скажем, delComment) и отдельно - функцию удаления статьи (delArticle), из которой будет вызываться delComment для всех комментариев статьи. Процедура удаления даже одного коммента может рассматриваться, как единая транзакция, т.к. внутри нее может быть множество операций с БД (напр., обновление каких-нибудь счетчиков, связей, состояний, уведомлений и проч.). Удаление статьи - это тоже единая транзакция, т.к. с точки зрения целостности - если уж статью удаляем, то обязательно все комменты должны быть удалены. Причем, при нормально работающем механизме вложенных транзакций не имеет значения, чего мы сделаем раньше - саму статью удалим, а потом комменты к ней или наоборот. Т.е. схематично это может выглядеть, скажем, так:
function delArticle($article) {
// начало транзакции 1
foreach ($article->comments as $comment) {
delComment($comment);
}
// прочие действия по удалению статьи
$article->delete;
// конец транзакции 1
}
function delComment($comment) {
// начало транзакции 2
// прочие действия по удалению комментария
$comment->delete;
// конец транзакции 2
}
Что произойдет, если beginTransaction() для "вложенных" (якобы) транзакций будет игнорироваться, а commit() и rollBack() - выполняться, сами представьте. Поэтому предложенный вариант не просто бесполезен - он очень вреден, т.к. будет ломать вложенные транзакции напрочь.
А вообще понятие “вложенных транзакций” - это вполне обычное дело в проектировании процедур работы с БД. И MySQL, насколько я знаю, их поддерживает. Но PDO про них, похоже не знает, и Yii-класс по работе с базой, видимо, тоже. Что совсем не айс для фреймворка