sverel
Новичок
Размышления о транзакциях
Допустим, есть класс для работы с деревьями NestedSets. Метод insert() выполняет набор SQL-запросов, которые должны либо быть выполнены все, либо ни один из них. Таким образом имеем что-то вроде:
Это базовый класс фреймворка, который давно написен, отлажен, оттестирован и отлично работает. Его трогать нельзя из-за философии.
Но в проекте надо сделать связанные данные и это тоже надо делать в транзакции. Получается вот так:
В итоге сталкиваюсь с вложенными транзакциями, которые не поддерживаются в MySQL и ничего не работает
.
Отличным выходом, как мне кажется, является старт транзакций в начале скрипта и коммит в самом конце. Из всех методов, естественно, придётся выкинуть start/stop transaction. Это надо сделать всего один раз и больше никогда не думать о целостности данных при написании различных методов. Т.е. пишем в index.php (и во всех остальных точках входа):
! Главное не писать commit() в деструкторе который выполнится даже при вызове die(); из середины программы.
Или ещё лучше: в конструкторе который создаёт объект $SQL написать start, а в деструкторе поставить rollback. Тогда в конец index.php останется только поставить commit.
Такой глобальный подход намного проще: теперь можно забыть про целостность данных решив эту проблему раз и на всегда и одновременно решить проблему вложенных транзакций. По моему, вполне логично. Но настараживает тот факт, что все CMS/CMF которые я анализировал использовали именно локальные внутриметодовые транзакции и нигде я не видел глобальные транзакции.
Хотя ещё больше меня настараживает тот факт, что большинство движков вообще не используют транзакции (wordpress, mzz, drupal и даже PEAR-класс DB_NestedSet). Странно как-то. Неужели в 2010 году все сервера работают настолько стабильно, что никому уже не нужны транзакции или всем плевать на целостность данных?
Допустим, есть класс для работы с деревьями NestedSets. Метод insert() выполняет набор SQL-запросов, которые должны либо быть выполнены все, либо ни один из них. Таким образом имеем что-то вроде:
PHP:
class DB_NESTEDSETS {
function insert(...) {
$SQL->transactionStart();
// .... выполняем всё что нужно ...
$SQL->transactionCommit();
}
}
Но в проекте надо сделать связанные данные и это тоже надо делать в транзакции. Получается вот так:
PHP:
$SQL->startTransaction();
$dbTree->insert(...); // NestedSets
$dbRelationObjects->update(...); // связь
$SQL->transactionCommit();

Отличным выходом, как мне кажется, является старт транзакций в начале скрипта и коммит в самом конце. Из всех методов, естественно, придётся выкинуть start/stop transaction. Это надо сделать всего один раз и больше никогда не думать о целостности данных при написании различных методов. Т.е. пишем в index.php (и во всех остальных точках входа):
PHP:
$SQL->transactionStart();
$application = new APP();
$application->start();
$SQL->transactionCommit();
Или ещё лучше: в конструкторе который создаёт объект $SQL написать start, а в деструкторе поставить rollback. Тогда в конец index.php останется только поставить commit.
Такой глобальный подход намного проще: теперь можно забыть про целостность данных решив эту проблему раз и на всегда и одновременно решить проблему вложенных транзакций. По моему, вполне логично. Но настараживает тот факт, что все CMS/CMF которые я анализировал использовали именно локальные внутриметодовые транзакции и нигде я не видел глобальные транзакции.
Хотя ещё больше меня настараживает тот факт, что большинство движков вообще не используют транзакции (wordpress, mzz, drupal и даже PEAR-класс DB_NestedSet). Странно как-то. Неужели в 2010 году все сервера работают настолько стабильно, что никому уже не нужны транзакции или всем плевать на целостность данных?