#php #mysql #transactions #mysqli
#php #mysql #транзакции #mysqli
Вопрос:
Я читал о транзакциях mysql, и у меня сложилось впечатление, что для создания транзакций нужно использовать либо mysqli, либо PDO. Тем не менее, я вижу повсюду примеры stack exchange и других сайтов, которые используют расширение mysql, подобное этому:
mysql_query("START TRANSACTION");
$rollback=0
if (!mysql_query($query1)){
$rollback=1
}
if (!mysql_query($query2)){
$rollback=1
}
if (!mysql_query($query3)){
$rollback=1
}
if ($rollback == 1){
mysql_query("ROLLBACK");
}
else{
mysql_query("COMMIT");
}
В чем разница между выполнением этого способа и использованием «специальных» функций mysqli, специфичных для mysqli mysqli::rollback и mysqli::commit?
Кроме того, что произойдет, если произойдет сбой php-скрипта (Т. Е. Сбой моего сервера приложений и т. Д.), Сервер БД автоматически откатит транзакцию после установленного периода времени?
Аналогично, что произойдет, если сервер БД выйдет из строя до mysql_query («COMMIT»)? Будет ли транзакция «откатываться»?
Спасибо!
Ответ №1:
Это также совершенно законно и использует инструкции MySQL непосредственно для реализации транзакции.
И, честно говоря, я не вижу никаких улучшений при использовании синтаксиса mysqli. Это неудачная абстракция, поскольку она отображает 1: 1 только для MySQL. Было бы разумнее использовать синтаксис более высокого уровня в PDO, поскольку он будет отображаться с другим синтаксисом в соответствии с базовой базой данных.
Однако, как говорит Хакре: mysqli предпочтительнее for performance and interoperability reasons, it's the recommended mysql lib in PHP.
Аналогично, что произойдет, если сервер БД выйдет из строя до mysql_query («COMMIT»)? Будет ли транзакция «откатываться»?
Проще, чтобы сбой прикладной программы, а не сервера БД. Любая не зафиксированная транзакция будет откатываться.
Также транзакцию можно откатить, потому что она не может получить блокировку в течение определенного времени ожидания.
Тайм-аут в секундах транзакция InnoDB может ожидать блокировки строки, прежде чем сдаться. Значение по умолчанию — 50 секунд. Транзакция, которая пытается получить доступ к строке, заблокированной другой транзакцией InnoDB, зависнет не более чем на столько секунд, прежде чем выдаст следующую ошибку:
ОШИБКА 1205 (HY000): превышен тайм-аут ожидания блокировки; попробуйте перезапустить транзакцию
Комментарии:
1. Итак, если я не использую подготовленные операторы или объектно-ориентированную нотацию, мне действительно нет необходимости переключаться на mysqli? Почему в этом так много путаницы? Похоже, многие люди считают, что вы не можете использовать mysql / ext для транзакций. Т.Е., Если вы посмотрите mysql против mysqli, большой точкой отсчета для mysqli кажутся транзакции, когда они возможны с использованием mysql… Есть ли «ошибка», о которой я должен знать, или люди просто фанаты?
2. @billmalarky: вы должны использовать mysqli по соображениям производительности и совместимости, это рекомендуемая библиотека mysql в PHP. MySQL (без i) больше не привлекает особого внимания, вы в основном работаете со старым кодом.
3. @stivlo Кроме того, если сервер БД выходит из строя, вы как бы в затруднительном положении? Например, может быть, транзакция будет зафиксирована, а может и нет, в зависимости от удачи (у меня сложилось впечатление, что perfect ACID невозможен).
4. @stilvo, при разрыве соединения транзакция всегда будет откатываться, потому что при повторном подключении будет выдан откат, независимо от таймаутов.
5. Вы говорите «если я не использую подготовленные операторы», как будто это то, чего вы бы не сделали. Лично я придерживаюсь мнения, что подготовленные инструкции — единственный действительно безопасный способ защитить себя от SQL Inection. При использовании mysql_real_escape_string слишком легко забыть его использовать или наивно оставить его включенным для чего-то, что вы считаете целым числом (потому что в PHP все переменные являются динамическими). Если вы используете только подготовленные операторы, то внедрение SQL невозможно.