PDO를 통해 연결됩니다. 쿼리를 시작하기 전에 먼저 PDO가 트랜잭션을 관리하는 방법을 이해해야 합니다. 트랜잭션은 원자성, 일관성, 격리성, 내구성이라는 네 가지 주요 특성(ACID)을 지원합니다. 일반인의 관점에서 보면 트랜잭션 내에서 수행되는 모든 작업은 단계적으로 수행되더라도 데이터베이스에 안전하게 적용되고 다른 연결의 간섭 없이 커밋된다는 것이 보장됩니다. 요청 시 트랜잭션 작업을 자동으로 취소할 수도 있으므로(아직 커밋되지 않은 경우) 스크립트 오류를 더 쉽게 처리할 수 있습니다.
트랜잭션은 일반적으로 일괄 변경 사항을 "누적"하고 동시에 적용함으로써 구현됩니다. 이렇게 하면 이러한 변경 사항의 효율성이 크게 향상될 수 있다는 장점이 있습니다. 즉, 트랜잭션을 통해 스크립트를 더 빠르고 잠재적으로 더 강력하게 만들 수 있습니다(단, 이러한 이점을 얻으려면 트랜잭션을 올바르게 사용해야 함).
안타깝게도 모든 데이터베이스가 트랜잭션을 지원하는 것은 아니므로 PDO는 연결이 처음 열릴 때 소위 "자동 커밋" 모드에서 실행되어야 합니다. 자동 커밋 모드는 데이터베이스가 지원하는 경우 각 쿼리 실행에 자체 암시적 트랜잭션이 있고 데이터베이스가 트랜잭션을 지원하지 않는 경우에는 없음을 의미합니다. 트랜잭션이 필요한 경우 PDO::beginTransaction() 메서드를 사용하여 시작해야 합니다. 기본 드라이버가 트랜잭션을 지원하지 않으면 PDOException이 발생합니다(이는 오류 처리 설정에 관계없이 심각한 오류 조건입니다). 트랜잭션이 시작되면 트랜잭션의 코드가 성공적으로 실행되었는지 여부에 따라 PDO::commit() 또는 PDO::rollBack()을 사용하여 완료할 수 있습니다.
PDO는 드라이버 계층에서 트랜잭션 처리 기능이 있는지 여부만 확인합니다. 일부 런타임 조건이 트랜잭션을 사용할 수 없음을 의미하고 데이터베이스 서비스가 트랜잭션 시작 요청을 수락하는 경우 PDO::beginTransaction()은 오류 없이 계속 TRUE를 반환합니다.
이에 대한 좋은 예는 MySQL 데이터베이스의 MyISAM 테이블에서 트랜잭션을 사용하려는 것입니다.
스크립트가 종료되거나 연결이 닫히려고 할 때 완료되지 않은 트랜잭션이 있으면 PDO가 자동으로 트랜잭션을 롤백합니다. 이 안전 조치는 스크립트가 예기치 않게 종료되는 경우 불일치를 방지하는 데 도움이 됩니다. 트랜잭션이 명시적으로 커밋되지 않은 경우 문제가 발생한 것으로 가정하므로 데이터를 안전하게 유지하기 위해 롤백이 수행됩니다.
자동 롤백은 PDO::beginTransaction()을 통해 트랜잭션을 시작한 후에만 발생할 수 있습니다. 트랜잭션을 시작하기 위해 쿼리를 수동으로 발행하는 경우 PDO는 이를 알 수 없으며 필요한 경우 롤백할 수 없습니다.
예제 #1 트랜잭션에서 일괄 처리 실행
다음 예에서는 신입 사원에 대한 항목 집합이 생성되고 ID 23이 할당되었다고 가정합니다. 개인의 기본 데이터를 등록하는 것 외에도 급여를 기록하는 것도 필요합니다. 두 업데이트를 별도로 완료하는 것은 간단하지만 PDO::beginTransaction() 및 PDO::commit() 호출에 포함하면 완료될 때까지 다른 사람이 변경 사항을 볼 수 없도록 할 수 있습니다. 오류가 발생하면 catch 블록은 트랜잭션이 시작된 이후 발생한 모든 변경 사항을 롤백하고 오류 메시지를 인쇄합니다.
<?php try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO::ATTR_PERSISTENT => true)); echo "Connected\n"; } catch (Exception $e) { die("Unable to connect: " . $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 "Failed: " . $e->getMessage(); } ?>
은 트랜잭션 내 변경에만 국한되지 않고 복잡한 쿼리를 실행하여 데이터를 추출할 수도 있으며 해당 정보를 사용하여 트랜잭션이 활성화될 때 더 많은 변경 사항과 쿼리를 작성할 수 있지만 다른 사람은 이를 수행할 수 없습니다. 작업이 진행되는 동안 변경하십시오.