Транзакции и автоматическая фиксация изменений
 
  После подключения к базе данных средствами модуля PDO потребуется понять,
  как PDO управляет транзакциями, прежде чем отправлять запросы.
  Тем, кто прежде не сталкивались с транзакциями, полезно знать 4 главных
  характеристики транзакций: атомарность, согласованность, изолированность и долговечность
  (англ. Atomicity, Consistency, Isolation and Durability, или ACID). Говоря простым языком,
  транзакция гарантирует, что каждая операция с базой данных выполнится безопасно
  и без помех со стороны других подключений, даже если операция
  выполняется поэтапно. Транзакционные операции автоматически отменяются
  по запросу, если транзакцию ещё не зафиксировали, что упрощает обработку
  ошибок в скриптах.
 
 
  Работа механизма транзакций часто состоит в «накоплении» пакета изменений,
  которые затем выполняются как одно целое; приятный побочный эффект такой работы
  состоит в резком увеличении эффективности этих обновлений. Другими словами,
  транзакции ускоряют скрипты и потенциально повышают их надёжность,
  хотя для этого и потребуется правильно работать с транзакциями, чтобы получить эти преимущества.
 
 
  Не каждая база данных поддерживает транзакции, поэтому при первом подключении
  модуль PDO вынужден работать в так называемом режиме «автоматической фиксации».
  В режиме автофиксации модуль оборачивает каждый запрос к базе данных
  в неявную транзакцию, если СУБД поддерживает транзакции,
  или выполняет отдельные запросы, если база данных не поддерживает механизм транзакций.
  Явное начало транзакции обозначают вызовом
  метода PDO::beginTransaction(). Независимо от настроек обработки ошибок
  модуль выбросит исключение PDOException, если нижележащий драйвер не поддерживает механизм транзакций,
  поскольку попытка начать транзакцию без поддержки драйвера — серьёзная ошибка. Внутри транзакции
  изменения фиксируют методом PDO::commit(), если код выполнился успешно,
  или откатывают транзакцию методом PDO::rollBack(),
  если при запуске кода в течение транзакции возникла ошибка.
 
 Внимание
  
   Модуль PDO проверяет доступность транзакций только на уровне драйвера.
   Метод PDO::beginTransaction() вернёт true без ошибок,
   если сервер базы данных примет запрос на запуск транзакции,
   даже если в конкретных условиях при выполнении запроса выяснится, что транзакции недоступны.
  
  
   К таким примерам относится попытка запуска транзакций в таблицах
   MyISAM базы данных MySQL.
  
  
 Внимание
  
   Неявные фиксации при выполнении DDL-запросов:
   Отдельные базы данных неявно выполняют команду COMMIT
   и фиксируют изменения в одной транзакции при выполнении серии DDL-запросов (англ. Database Definition Language)
   наподобие DROP TABLE или CREATE TABLE.
   Поэтому изменения, которые оказались в транзакции,
   автоматически фиксируются, и откатить такие изменения
   невозможно.
  
  
   К примерам баз данных с таким поведением относятся СУБД MySQL
   и Oracle.
  
  
 
  
   Пример #1 Пример неявной фиксации
   
<?php
$pdo->beginTransaction();
$pdo->exec("INSERT INTO users (name) VALUES ('Rasmus')");
$pdo->exec("CREATE TABLE test (id INT PRIMARY KEY)"); // Неявная фиксация командой COMMIT выполняется в этом месте
$pdo->rollBack(); // Невозможно отменить серию команд INSERT/CREATE в БД MySQL или Oracle
?>
    
   
 
 
  Лучшая практика: При работе с базами данных с таким поведением
  рекомендуют избегать выполнения DDL-запросов внутри транзакций. DDL-операции исключают
  из транзакционной логики, когда требуется.
 
 
  Модуль PDO автоматически откатит невыполненные транзакции при завершении работы скрипта
  или при закрытии соединения. Откат транзакций — мера безопасности, которая помогает избегать
  нарушения целостности данных, когда скрипт неожиданно прерывает работу.
  Модуль предполагает, что взаимодействие с базой данных нарушилось, раз изменения не зафиксировали явным образом,
  и откатывает изменения для безопасности данных.
 
 Внимание
  
   Изменения откатятся автоматически, только если транзакцию открыли методом
   PDO::beginTransaction(). При ручной отправке запроса, который начинает транзакцию,
   PDO не узнает об этом, поэтому не откатит транзакцию при сбое.
  
  
 
  
Пример #2 Выполнение пакета изменений в рамках транзакции
   
    В следующем примере предположим, что требуется создать набор записей для нового
    сотрудника с идентификатором 23. Кроме ввода базовой информации о сотруднике потребуется
    записать его зарплату. Вместо двух отдельных изменений
    обернём обновление таблиц методами
    PDO::beginTransaction()
    и PDO::commit(), чтобы гарантировать, что никто другой не увидит
    этих изменений, пока вставка данных не завершится. При сбое
    блок catch откатит изменения, которые внесли с момента начала транзакции, и выведет сообщение
    об ошибке.
   
<?php
try {
    $dbh = new PDO(
        'odbc:SAMPLE',
        'db2inst1',
        'ibmdb2',
        array(PDO::ATTR_PERSISTENT => true)
    );
    echo "Подключились\n";
} 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();
}
?>
    
  
  Транзакции не ограничивают разработчика только изменением данных; в транзакции заворачивают
  сложные запросы для извлечения данных, на основе которых
  создают больше запросов на обновление и другие запросы; активная
  транзакция гарантирует, что никто не изменит данные,
  пока идёт работа с транзакцией. Дополнительную информацию о транзакциях
  содержит документация к серверу баз данных.