PDO Транзакции

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 (); 
  } 

Вы не ограничены в выполнении запросов в транзакции, вы можете даже создавать сложные запросы для извлечения данных и, возможно, использовать полученную информацию для создания других запросов, во время активной транзакции, вам гарантируется, что никто другой не может сделать изменения в то время, когда вы находитесь в процессе вашей работы. А изменения привнесённые транзакцией, как говорилось выше сохраняться в базе данных все и сразу.

Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 95 гостей онлайн