PDO 기반 데이터베이스 조작 클래스와 트랜잭션 처리 예제

기존에 작성된 PDO 기반 데이터베이스 조작 함수를 개선하여 재구성한 예제로, 기본적인 CRUD 연산을 간소화하고 트랜잭션 지원을 통해 데이터 일관성을 보장할 수 있도록 구성하였다.

<?php
/**
 * PDO 기반 데이터베이스 조작 헬퍼 함수 모음
 * 작성일: 2011-03-19 (수정: 2011-06-30)
 */

// 전역 PDO 인스턴스 필요
global $pdo;

/**
 * 데이터 조회 (SELECT)
 * 
 * @param bool   $debug    디버그 모드 활성화 여부
 * @param int    $type     반환 유형 (0: 전체 레코드 배열, 1: 단일 레코드, 2: 카운트)
 * @param string $table    테이블 이름
 * @param string $columns  조회할 컬럼 (기본값: *)
 * @param string $where    조건절 (기본값 없음)
 * @param string $sort     정렬 조건 (기본값: id 내림차순)
 * @return mixed           지정된 형식의 결과 반환
 */
function fetchRecords($debug, $type, $table, $columns = '*', $where = '', $sort = 'id DESC') {
    global $pdo;
    
    $baseQuery = "SELECT {$columns} FROM {$table} WHERE 1=1 {$where}";
    $countQuery = "SELECT COUNT(*) FROM {$table} WHERE 1=1 {$where}";
    
    if ($debug) {
        $query = ($type === 2) ? $countQuery : "{$baseQuery} ORDER BY {$sort}";
        echo $query;
        exit;
    }

    try {
        if ($type === 2) {
            $stmt = $pdo->query($countQuery);
            return $stmt->fetchColumn();
        } elseif ($type === 1) {
            $stmt = $pdo->query($baseQuery);
            return $stmt->fetch(PDO::FETCH_ASSOC);
        } else {
            $stmt = $pdo->query("{$baseQuery} ORDER BY {$sort}");
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
    } catch (PDOException $e) {
        error_log('Fetch Error: ' . $e->getMessage());
        return ($type === 2) ? 0 : [];
    }
}

/**
 * 데이터 삽입 (INSERT)
 * 
 * @param bool   $debug    디버그 모드 여부
 * @param int    $returnType 반환 유형 (0: 무반환, 1: 영향받은 행 수, 2: 생성된 ID)
 * @param string $table    테이블 이름
 * @param string $fields   삽입할 컬럼 목록
 * @param string $data     삽입할 값 목록
 * @return mixed
 */
function insertRecord($debug, $returnType, $table, $fields, $data) {
    global $pdo;
    $query = "INSERT INTO {$table} ({$fields}) VALUES ({$data})";
    
    if ($debug) {
        echo $query;
        exit;
    }

    try {
        $affected = $pdo->exec($query);
        if ($returnType === 2) {
            return $pdo->lastInsertId();
        } elseif ($returnType === 1) {
            return $affected;
        }
        // 기본 동작: 성공 시 종료하지 않음
    } catch (PDOException $e) {
        error_log('Insert Error: ' . $e->getMessage());
        throw $e;
    }
}

/**
 * 데이터 수정 (UPDATE)
 * 
 * @param bool   $debug    디버그 모드 여부
 * @param int    $returnType 반환 유형 (0: 무반환, 1: 영향받은 행 수)
 * @param string $table    테이블 이름
 * @param string $updates  SET 절 문자열 (예: name='test', age=25)
 * @param string $where    조건절 (기본값 없음)
 * @return mixed
 */
function updateRecord($debug, $returnType, $table, $updates, $where = '') {
    global $pdo;
    $query = "UPDATE {$table} SET {$updates} WHERE 1=1 {$where}";
    
    if ($debug) {
        echo $query;
        exit;
    }

    try {
        if ($returnType === 1) {
            return $pdo->exec($query);
        } else {
            $pdo->exec($query);
        }
    } catch (PDOException $e) {
        error_log('Update Error: ' . $e->getMessage());
        throw $e;
    }
}

/**
 * 데이터 삭제 (DELETE)
 * 
 * @param bool   $debug    디버그 모드 여부
 * @param int    $returnType 반환 유형 (0: 무반환, 1: 영향받은 행 수)
 * @param string $table    테이블 이름
 * @param string $where    조건절 (기본값 없음)
 * @return mixed
 */
function deleteRecord($debug, $returnType, $table, $where = '') {
    global $pdo;
    $query = "DELETE FROM {$table} WHERE 1=1 {$where}";
    
    if ($debug) {
        echo $query;
        exit;
    }

    try {
        if ($returnType === 1) {
            return $pdo->exec($query);
        } else {
            $pdo->exec($query);
        }
    } catch (PDOException $e) {
        error_log('Delete Error: ' . $e->getMessage());
        throw $e;
    }
}
?>

아래는 위의 함수들을 활용한 PDO 트랜잭션 처리 예제이다. 트랜잭션은 데이터 무결성을 유지하기 위해 여러 쿼리가 하나의 논리적 작업 단위로 처리되도록 보장한다. MySQL의 경우 InnoDB 스토리지 엔진에서만 트랜잭션이 지원된다.

try {
    // 트랜잭션 시작
    $pdo->beginTransaction();

    // 성공할 쿼리
    insertRecord(false, 1, 'category', 'title,parent_id', "'신규카테고리', 0");

    // 오류 발생 쿼리 (컬럼 불일치 등)
    insertRecord(false, 1, 'tb_searchlog', 'user_id,action', '4');

    // 모든 쿼리 성공 시 커밋
    $pdo->commit();
    echo "모든 작업이 성공적으로 완료되었습니다.";
} catch (Exception $e) {
    // 예외 발생 시 롤백
    $pdo->rollBack();
    echo "작업 실패: " . $e->getMessage();
}

이 방식은 사용자 입력 기반의 다단계 데이터 조작 시 안정성을 높이며, 중간에 실패할 경우 원자성을 유지하여 부분 적용되는 것을 방지한다.

태그: PDO PHP MySQL 트랜잭션 데이터베이스

9월 5일 02:02에 게시됨