12. 트랜잭션 (Transactions)
트랜잭션(Transaction)이란?
트랜잭션은 데이터베이스에서 논리적인 작업 단위를 의미합니다. 하나 이상의 SQL 명령을 묶어서 실행하며, 모든 명령이 성공적으로 실행될 경우에만 결과를 반영하고, 하나라도 실패할 경우 롤백하여 이전 상태로 되돌리는 기능을 제공합니다.
예제: 트랜잭션 사용하기
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "mydatabase"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 트랜잭션 시작 $conn->beginTransaction(); // 데이터 삽입 $sql1 = "INSERT INTO users (username, password) VALUES ('john_doe', 'password123')"; $conn->exec($sql1); // 데이터 수정 $sql2 = "UPDATE users SET email='new_email@example.com' WHERE username='john_doe'"; $conn->exec($sql2); // 모든 SQL 문이 성공적으로 실행되면 커밋 $conn->commit(); echo "Transaction committed successfully"; } catch(PDOException $e) { // 오류 발생 시 롤백 $conn->rollback(); echo "Transaction failed: " . $e->getMessage(); } ?>
준비된 쿼리 (Prepared Statements)
준비된 쿼리(Prepared Statements)란?
준비된 쿼리는 미리 준비된 SQL 템플릿을 의미합니다. 이 템플릿에는 실행 시점에 입력할 수 있는 매개변수가 포함되어 있습니다. 이를 통해 SQL 삽입 공격을 방지하고 성능을 향상시킬 수 있습니다.
예제: 준비된 쿼리 사용하기 (PDO)
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "mydatabase"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 준비된 쿼리 준비 $stmt = $conn->prepare("SELECT * FROM users WHERE username = :username AND password = :password"); // 매개변수 바인딩 $username = 'john_doe'; $password = 'password123'; $stmt->bindParam(':username', $username); $stmt->bindParam(':password', $password); // 쿼리 실행 $stmt->execute(); // 결과 가져오기 $result = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($result as $row) { echo "Username: " . $row["username"] . "<br>"; } } catch(PDOException $e) { echo "Error: " . $e->getMessage(); } ?>
데이터베이스 보안 (SQL Injection Prevention)
SQL 삽입 공격(SQL Injection) 방지
SQL 삽입 공격은 사용자 입력값을 통해 조작된 SQL 쿼리를 실행하여 데이터베이스를 공격하는 기법입니다. 준비된 쿼리를 사용하거나 입력 값의 검증 및 이스케이프를 통해 방지할 수 있습니다.
예제: SQL 삽입 공격 방지하기
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "mydatabase"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 사용자 입력값 이스케이프 $username = addslashes($_POST['username']); $password = addslashes($_POST['password']); // 준비된 쿼리 준비 $stmt = $conn->prepare("SELECT * FROM users WHERE username = :username AND password = :password"); // 매개변수 바인딩 $stmt->bindParam(':username', $username); $stmt->bindParam(':password', $password); // 쿼리 실행 $stmt->execute(); // 결과 가져오기 $result = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($result as $row) { echo "Username: " . $row["username"] . "<br>"; } } catch(PDOException $e) { echo "Error: " . $e->getMessage(); } ?>
위 코드 예제들은 PHP에서 MySQL 데이터베이스와 작업을 할 때 중요한 보안적 측면을 강조하며, 트랜잭션과 준비된 쿼리를 통한 안전한 데이터베이스 처리 방법을 보여줍니다.