업무
CodeIgniter의 데이터베이스 추상화를 사용하면 트랜잭션 안전 테이블 유형을 지원하는 데이터베이스와 트랜잭션을 사용할 수 있습니다. MySQL에서는 보다 일반적인 MyISAM 대신 InnoDB 또는 BDB 테이블 유형을 실행해야 합니다. 대부분의 다른 데이터베이스 플랫폼은 기본적으로 트랜잭션을 지원합니다.
트랜잭션에 익숙하지 않은 경우 특정 데이터베이스에 대해 알아볼 수 있는 좋은 온라인 리소스를 찾는 것이 좋습니다. 아래 정보는 귀하가 거래에 대한 기본적인 이해를 가지고 있다고 가정합니다.
CodeIgniter의 거래 접근 방식
CodeIgniter는 널리 사용되는 데이터베이스 클래스 ADODB에서 사용하는 프로세스와 매우 유사한 트랜잭션 접근 방식을 활용합니다. 우리는 트랜잭션 실행 프로세스를 크게 단순화하기 때문에 이 접근 방식을 선택했습니다. 대부분의 경우 필요한 것은 두 줄의 코드뿐입니다.
전통적으로 트랜잭션에서는 쿼리를 추적하고 쿼리의 성공 또는 실패에 따라 커밋 또는 롤백 여부를 결정해야 하므로 구현하는 데 상당한 양의 작업이 필요했습니다. 이는 중첩된 쿼리의 경우 특히 번거롭습니다. 대조적으로, 우리는 이 모든 것을 자동으로 수행하는 스마트 거래 시스템을 구현했습니다(원하는 경우 거래를 수동으로 관리할 수도 있지만 실제로는 이점이 없습니다).
참고
v4.3.0부터 트랜잭션 중에 DBDebug가 true인 경우에도 기본적으로 예외가 발생하지 않습니다.
트랜잭션 실행
트랜잭션을 사용하여 쿼리를 실행하려면 다음과 같이 $this->db->transStart() 및 $this->db->transComplete() 메소드를 사용합니다:
<?php
$this->db->transStart();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->transComplete();
transStart()/transComplete() 메소드 사이에서 원하는 만큼 많은 쿼리를 실행할 수 있으며 해당 쿼리는 특정 쿼리의 성공 또는 실패에 따라 모두 커밋되거나 롤백됩니다.
엄격 모드
기본적으로 CodeIgniter는 Strict 모드에서 모든 트랜잭션을 실행합니다.
엄격 모드가 활성화되면 여러 트랜잭션 그룹을 실행하는 경우 한 그룹이 실패하면 모든 후속 그룹이 롤백됩니다.
엄격 모드가 비활성화되면 각 그룹은 독립적으로 처리됩니다. 즉, 한 그룹의 오류가 다른 그룹에 영향을 미치지 않습니다.
엄격 모드는 다음과 같이 비활성화할 수 있습니다.
<?php
$this->db->transStrict(false);
거래 상태 재설정
Added in version 4.6.0.
엄격 모드가 활성화되면 하나의 트랜잭션이 실패하면 모든 후속 트랜잭션이 롤백됩니다.
실패 후 트랜잭션을 다시 시작하려면 트랜잭션 상태를 재설정하면 됩니다.
<?php
$this->db->resetTransStatus();
오류 관리
참고
v4.3.0부터 트랜잭션 중에 DBDebug가 true인 경우에도 기본적으로 예외가 발생하지 않습니다.
다음과 같이 자신의 오류를 관리할 수 있습니다.
<?php
$this->db->transStart();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->transComplete();
if ($this->db->transStatus() === false) {
// generate an error... or use the log_message() function to log your error
}
예외 던지기
Added in version 4.3.0.
참고
v4.3.0부터 트랜잭션 중에 DBDebug가 true인 경우에도 기본적으로 예외가 발생하지 않습니다.
쿼리 오류가 발생할 때 예외가 발생하도록 하려면 $this->db->transException(true)를 사용할 수 있습니다:
<?php
// When DBDebug in the Database Config must be true.
use CodeIgniter\Database\Exceptions\DatabaseException;
try {
$this->db->transException(true)->transStart();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->transComplete();
} catch (DatabaseException $e) {
// Automatically rolled back already.
}
쿼리 오류가 발생하면 모든 쿼리가 롤백되고 DatabaseException이 발생합니다.
거래 비활성화
거래는 기본적으로 활성화되어 있습니다. 트랜잭션을 비활성화하려면 $this->db->transOff()를 사용하면 됩니다:
<?php
$this->db->transOff();
$this->db->transStart();
$this->db->query('AN SQL QUERY...');
$this->db->transComplete();
트랜잭션이 비활성화되면 트랜잭션 없이 쿼리를 실행할 때와 마찬가지로 쿼리가 자동 커밋됩니다.
테스트 모드
선택적으로 트랜잭션 시스템을 “테스트 모드”로 설정할 수 있습니다. 그러면 쿼리가 유효한 결과를 생성하는 경우에도 쿼리가 롤백됩니다. 테스트 모드를 사용하려면 $this->db->transStart() 메소드의 첫 번째 매개변수를 true로 설정하세요.
<?php
$this->db->transStart(true); // Query will be rolled back
$this->db->query('AN SQL QUERY...');
$this->db->transComplete();
수동으로 트랜잭션 실행
app/Config/Database.php 파일에 DBDebug false가 있고 트랜잭션을 수동으로 실행하려는 경우 다음과 같이 할 수 있습니다:
<?php
$this->db->transBegin();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
if ($this->db->transStatus() === false) {
$this->db->transRollback();
} else {
$this->db->transCommit();
}
참고
수동 트랜잭션을 실행할 때 $this->db->transBegin()을 사용하세요. NOT $this->db->transStart().
중첩된 트랜잭션
CodeIgniter에서는 가장 바깥쪽 또는 최상위 트랜잭션 명령만 실행되는 방식으로 트랜잭션을 중첩할 수 있습니다. 트랜잭션 블록 내에 원하는 만큼 transStart()/transComplete() 또는 transBegin()/transCommit()/transRollback() 쌍을 포함할 수 있습니다. CodeIgniter는 트랜잭션 “깊이”를 추적하고 가장 바깥쪽 레이어(깊이 0)에서만 조치를 취합니다.
<?php
$this->db->transStart(); // actually starts a transaction
$this->db->query('SOME QUERY 1 ...');
$this->db->transStart(); // doesn't necessarily start another transaction
$this->db->query('SOME QUERY 2 ...');
$this->db->transComplete(); // doesn't necessarily end the transaction, but required to finish the inner transaction
$this->db->query('SOME QUERY 3 ...');
$this->db->transComplete(); // actually ends the transaction
참고
구조가 훨씬 더 복잡한 경우 데이터베이스에서 완전히 실행되도록 내부 트랜잭션이 가장 바깥쪽 레이어에 다시 도달할 수 있도록 보장하여 의도하지 않은 커밋/롤백을 방지하는 것은 사용자의 책임입니다.