트랜잭션과 멀티 데이터소스
단일 DAO
$userDAO->startTransaction();
try {
$userDAO->insert($user);
$userDAO->commit();
} catch (Throwable $e) {
$userDAO->rollback();
throw $e;
}
여러 DAO에 걸친 트랜잭션
DataSourceManager로 전역 트랜잭션을 열면, 이후 실행되는 모든 데이터소스가 자동으로 트랜잭션에 참여합니다.
use _Flexagon\Libs\DataSourceManager;
DataSourceManager::startTransaction();
try {
$userDAO->insert($user);
$orderDAO->insert($order);
$pointDAO->update($point);
DataSourceManager::commit();
} catch (Throwable $e) {
DataSourceManager::rollback();
throw $e;
}
커밋과 롤백은 커넥션 등록 순서의 역순으로 수행됩니다.
DAO에 데이터소스 지정
DATA_SOURCE_ID 상수를 재정의합니다.
class StatsDAO extends BaseMySqlDAO {
const DATA_SOURCE_ID = 'analytics'; // _Global::$DATA_SOURCES['analytics']
protected string $tableName = 'daily_stats';
}
접속 실패 처리
데이터 소스에 접속하지 못하면 DAO 생성자가 _Flexagon\DB\ConnectionException을 던집니다(기본값 _Global::$DB_CONNECT_FAILURE_FATAL = true). 잡지 않으면 요청이 500으로, CLI는 종료 코드 255로 끝납니다. 응답을 직접 정하려면 잡으세요.
// public/_entry.php
set_exception_handler(function (Throwable $e) {
if ( $e instanceof \_Flexagon\DB\ConnectionException ) {
http_response_code(503);
TemplateLoader::show('maintenance');
return;
}
throw $e;
});
예외 메시지에는 데이터 소스 이름만 들어갑니다($e->getDataSourceId(), _Global::$DATA_SOURCES의 키). 호스트와 계정이 담긴 드라이버 메시지는 에러 로그로 가고, 원본 PDOException은 getPrevious()로 꺼낼 수 있습니다. 운영에서는 display_errors를 꺼 두세요. 잡지 않은 예외를 화면에 출력하면 이전 예외까지 함께 나옵니다.
예외 대신 connect()가 false를 반환하게 하려면 $DB_CONNECT_FAILURE_FATAL = false로 두세요.