PHP Транзакції та автоматична фіксація змін

Тепер ви знаєте, як підключатися до баз даних за допомогою PDO. Але перед тим, як виконувати запити, вам необхідно зрозуміти, як PDO керує транзакціями. Якщо ви раніше не стикалися з транзакціями, вони мають чотири основні властивості, це Атомарність, Узгодженість, Ізольованість і Довговічність (ACID). Говорячи простою мовою, будь-які дії, вчинені в рамках транзакції, гарантовано будуть виконані безпечно для бази даних, і на них не вплинуть інші підключення до цієї бази, навіть якщо ці дії здійснюються в декілька етапів. Транзакційні операції можна скасовувати на запит (якщо транзакція ще не зафіксована), що спрощує обробку помилок у скриптах.

Механізм транзакцій реалізований шляхом "тимчасового збереження" всіх змін та подальшого застосування цих змін як єдиного цілого. Це дозволяє досягти різкого збільшення ефективності таких змін. Іншими словами, транзакції можуть зробити ваші скрипти швидшими та потенційно стабільнішими (але для цього необхідно коректно використовувати цей механізм).

На жаль, не всі бази даних підтримують транзакції, тому PDO під час створення підключення працює в режимі так званої "автоматичної фіксації". Режим автофіксації означає, що кожен запит до бази даних, який ви виконуєте, неявно полягає в транзакції, якщо їх СУБД підтримує. Якщо база даних не підтримує цей механізм, запит опрацьовується без транзакції. Щоб явно визначити початок транзакції, ви повинні використовувати метод PDO::beginTransaction() . Якщо драйвер не підтримує механізм транзакцій, викинеться виняток PDOException (незалежно від обраного способу обробки помилок: подібні ситуації - цезавжди серйозна недоробка). Після того, як ви здійсните транзакцію, ви можете зафіксувати її методом PDO::commit() або відкотити методом PDO::rollBack() , залежно від того, чи успішно виконано ваш код усередині транзакції чи ні.

PDO перевіряє можливість використання транзакцій лише на рівні драйвера. Якщо з якихось причин механізм транзакцій недоступний, але сервер баз даних прийняв запит на відкриття транзакції, PDO::beginTransaction() повернеTRUE без помилок.

Як приклад може бути спроба використання транзакцій у таблицях MyISAM бази даних MySQL.

При завершенні роботи скрипта або при закритті з'єднання PDO автоматично відкочує всі незавершені транзакції. Це робиться, щоб запобігти порушенням цілісності бази даних у випадках, коли скрипт несподівано перериває роботу. Якщо ви явно не зафіксували зміни, то передбачається, що щось пішло не так. Тому відкат змін - найбезпечніший вихід із ситуації.

Зміни будуть відкачені автоматично, лише якщо транзакція відкрита методом PDO::beginTransaction(). Якщо транзакцію відкрити вручну в тексті запиту, PDO про це ніяк не дізнається, і, відповідно, не зможе вжити заходів, якщо станеться щось погане.

Приклад #1 Виконання пакета змін у рамках транзакції

У наступному прикладі припустимо, що ми створюємо кілька записів для нового співробітника з номером >PDO::beginTransaction() та PDO::commit() ми зможемо гарантувати, що ніхто не побачить цих змін, доки всі вони не будуть завершені. Якщо щось піде не так, catch-блок відкотить усі зміни з початку транзакції та надрукує повідомлення про помилку.

try $dbh = новий 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 -> почати Transaction (); $dbh -> exec ("insert into staff (id, first, last) values ​​(23, 'Joe', 'Bloggs')" ); $dbh -> exec ( "insert in salarychange (id, amount, changedate) values ​​(23, 50000, NOW())" ); $dbh -> commit();

> catch (Exception $e) $dbh -> rollBack(); echo "Помилка: ". $e -> getMessage(); > ?>

Ви не обмежені у кількості запитів у рамках транзакції; ви також можете виконувати складні запити, щоб витягти дані, а потім використовувати їх для створення інших запитів на оновлення та вилучення даних; якщо транзакція активна, ви можете бути впевнені, що ніхто не зможе змінити ваші дані, доки ви з ними працюєте. За додатковою інформацією про транзакції зверніться до документації до сервера баз даних.