PDO Транзакции
Теперь, когда вы подключены к базе данных с помощью PDO, необходимо уразуметь, как оно управляет транзакциями. Транзакции дают четыре основных преимущества: атомарность, целостность, изоляция и долговечность (ACID).
С точки зрения непрофессионала любая работа, проделанная в транзакции, даже если она осуществляется поэтапно, гарантированно будет применена к базе данных безопасно и без помех со стороны других подключений(если они совершаются в тот же момент). Изменения, которые привнесли в базу данных транзакции можно также автоматически отменить по Вашему желанию, что делает обработку ошибок в скриптах проще.
Транзакции, как правило, осуществляются "по накоплению" т.е. посланные данные будут накапливаться, а потом, когда Вы зафиксируете транзакцию они будут обработаны быстро и полностью. У этого принципа есть хороший побочный эффект высокая эффективность обработки данных. Другими словами транзакции могут сделать Ваши сценарии быстрее и стабильнее (Но Вы должны использовать их правильно, чтобы иметь это преимущество).
К сожалению, не каждая база данных поддерживает транзакции, поэтому, когда вы впервые открываете соединение, PDO приходиться работать в так называемом режиме "авто фиксации". Режим автоматической фиксации означает, что у каждого запроса, который Вы выполняете, есть своя собственная неявная транзакция, если база данных поддерживает их, и нет никакой - такой транзакции, если база данных их не поддерживает.
Если Вам нужно осуществить транзакцию, вы должны использовать PDO:: BeginTransaction (), чтобы инициировать её. Если основной драйвер не поддерживает транзакции, будет выброшен объект PDOException (вне зависимости от настройки обработки ошибок: Имейте это ввиду!). Когда вы находитесь в процессе транзакции можно использовать PDO::commit () для фиксации и PDO::Rollback() для отката.
Имейте ввиду:
PDO лишь проверяет возможность транзакции на уровне драйвера. Если определенные условия времени выполнения и сложатся так, что транзакции будут не возможны, PDO:: beginTransaction () все еще возвратит TRUE без ошибки, если сервер базы данных разрешит, запросу запустить транзакцию. Но в итоге может произойти облом. В этом можно убедиться, запустив транзакцию к таблице MyISAM в базе данных MySQL. Если скрипт завершился, или вдруг оборвалось соединение с базой, если у вас есть открытые транзакции, PDO автоматически выполнит их откат. Это мера безопасности, чтобы избежать несогласованности в тех случаях, когда сценарий завершается неожиданно - если вы явно не фиксируете транзакцию, то предполагается, что что-то пошло не так, поэтому откат выполняется для безопасности ваших данных.
Кстати:
Автоматический откат происходит только, если Вы инициируете транзакцию явно через PDO:: beginTransaction (). В любом другом случае, PDO не знает о транзакции и не сможет откатить её, если что-то пошло не так.
Выполнение нескольких запросов в транзакции.
В следующем примере, давайте предположим, что мы создаем набор записей для нового сотрудника, которому был присвоен идентификационный номер 23. Кроме ввода исходных данных для этого человека, мы также должны записывать зарплаты в другую таблицу. Это довольно просто сделать двумя отдельными запросами, заключив их между PDO:: BeginTransaction () и PDO::Commit () - мы гарантируем, что пока эти два запроса не выполнятся успешно, никаких изменений в базе данных не произойдёт. Т.е. либо оба, либо ни одного.
Если что-то пойдет не так, блок catch откатывает все изменения, сделанные после начала транзакции, а затем выводит сообщение об ошибке.
try { $dbh = new PDO ( 'mysql:dbname=my_base' , 'root' , '' , array( PDO :: ATTR_PERSISTENT => true )); echo "Есть контакт! Поехали…" ; } catch ( Exception $e ) { die( "Соединение не прошло: " . $e -> getMessage ()); } try { $dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION ); $dbh -> beginTransaction (); $dbh -> exec ( "insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')" ); $dbh -> exec ( "insert into salarychange (id, amount, changedate) values (23, 50000, NOW())" ); $dbh -> commit (); } catch ( Exception $e ) { $dbh -> rollBack (); echo "Шеф! Фсё пропало : " . $e -> getMessage (); }
Вы не ограничены в выполнении запросов в транзакции, вы можете даже создавать сложные запросы для извлечения данных и, возможно, использовать полученную информацию для создания других запросов, во время активной транзакции, вам гарантируется, что никто другой не может сделать изменения в то время, когда вы находитесь в процессе вашей работы. А изменения привнесённые транзакцией, как говорилось выше сохраняться в базе данных все и сразу.
Информация копипастерам
Внимание! Копирование контента с сайта, возможно только с разрешения администратора. Т.е. Меня! Я скорее всего разрешу Вам это сделать, в обмен на живую ссылку, на статью оригинал.