안녕하세요 오늘은 PHP에서 데이터베이스 트랜잭션을 처리하는 방법을 알아보겠습니다.
저희가 코딩을 하며 프로그램을 짜다보면 다양한 예외상황을 맞이하게 되는 데 그럴 때마다 저희는 예외처리를 통해 데이터들을 롤백해주거나 재시도 하는 작업을 하죠? 그런 게 데이터베이스 트랜잭션을 처리하는 과정입니다.
하지만 그 과정을 좀 더 쉽게 만들어주는 메소드가 있습니다!
그것은 바로 mysqli_rollback() 메소드로 해당 스크립트에서 이전에 했던 작업들을 전부 롤백시키는 기능을 합니다.
예를 들어 돈을 송금하는 스크립트인데 데이터베이스에서는 돈을 출금했다고 잔액을 깎는 쿼리가 실행되었는데 그 후 전산상에 문제가 생겨 실제 송금에는 실패했을 경우 잔액이 사라지는 문제가 생깁니다.
이 때 당연히 저희는 그 쿼리를 되돌려줘야 하는 데 되돌려야 하는 작업이 여러개라면 번거로워지죠?
이런 경우에 방금 말한 mysqli_rollback()메소드를 사용하면 됩니다!
먼저 PHP에서는 기본적은로 AUTO_COMMIT이 활성화 되어있어 실행되는 쿼리가 바로 데이터베이스에 반영됩니다.
하지만 데이터베이스 트랜잭션 처리를 하기 위해선 AUTO_COMMIT을 비활성화 시켜야 합니다.
그래야 쿼리를 실행시켜도 즉각적으로 데이터베이스에 반영되지 않습니다.
처리 순서는 다음과 같습니다.
1. mysqli_autocommit 함수를 통해 autocommit 비활성화(false)
2. insert, delete 작업 등
3. 만약 실패시 mysqli_rollback 함수를 통해 데이터 롤백
4. 최종 성공시 mysqli_commit (수동 커밋)
5. mysqli_autocommit 함수를 통해 autocommit 활성화(true)
다음은 예제 코드입니다.
사용자 테이블에 사용자 정보를 입력함과 동시에 반드시 카테고리, 사용자의 이미지 패스를 저장해야 합니다.
이 때 카테고리 및 사용자 이미지패스를 저장할 때 한번이라도 실패하는 경우 데이터를 롤백해주겠습니다.
class Database { // 데이터베이스 관련 클래스
private $host_name = "localhost";
private $host_id = "root";
private $host_password = "root";
private $db_name = "test";
private $conn;
private function __construct() { // db 객체 초기화
$this->conn = mysqli_connect($this->host_name, $this->user_name, $this->user_password);
mysqli_select_db($this->conn, $this->db_name);
mysqli_set_charset($this->conn, "utf8");
}
public function get_insert_id() { // 저장된 마지막 PK 값 가져오는 메소드
$id = mysqli_insert_id($this->conn);
return $id;
}
// 사용자 정보 저장 및 카테고리, 이미지 패스 저장 메소
public function addMember($user_id, $title, $context, $thumbnail_path, $image_path, $category) {
// mysqli_begin_transaction($this->conn); 해당 코드를 오토커밋 방식 대신 사용할 수도 있다.
mysqli_autocommit($this->conn, FALSE);
$query = "INSERT INTO `member` VALUES (NULL , '{$user_id}', '{$title}', '{$context}', NOW(), '{$thumbnail_path}')";
$result = @mysqli_query($this->conn, $query);
$id = get_insert_id();
if ($result) {
foreach($category as $value) { // 카테고리 저장 및 실패 시 롤백
$result = $this->addCategory($id, $value);
if (!$result) {
mysqli_rollback($this->conn);
return FALSE;
}
}
foreach($image_path as $path) { // 이미지 패스 저장 및 실패 시 롤백
$result = $this->addImage($id, $path);
if (!$result) {
mysqli_rollback($this->conn);
return FALSE;
}
}
mysqli_commit($this->conn);
mysqli_autocommit($this->conn, TRUE);
return TRUE;
}
return FALSE;
}
//카테고리 추가
public function addCategory($user_id, $category_id) {
$query = "INSERT INTO `member_categorys` VALUES (NULL, '{$user_id}', '{$category_id}')";
$result = @mysqli_query($this->conn, $query);
return $result;
}
//이미지 추가
public function addImage($user_id, $image_path) {
$query = "INSERT INTO `member_images` VALUES (NULL, '{$user_id}', '{$image_path}')";
$result = @mysqli_query($this->conn, $query);
return $result;
}
}
이렇게 롤백 메소드를 사용하면 편리하게 데이터베이스 트랜잭션을 처리할 수 있습니다~
감사합니다.
'PHP' 카테고리의 다른 글
[PHP] 데이터베이스 인덱스 처리하는 방법 (0) | 2024.01.14 |
---|---|
[PHP]PHP에서 로그 남기기 (2) | 2024.01.08 |
[PHP] 정규 표현식 메소드 사용법 (2) | 2024.01.01 |
[PHP] PHP에서 문자열 다루기와 주요 함수 (0) | 2023.12.30 |
[PHP] 폼 처리와 사용자 입력 (2) | 2023.12.21 |