본문 바로가기

프로그래밍/PHP

PHP DB트랜잭션(DB Transaction) 처리방법



PHP에서 데이터베이스 프로그래밍을 할때,

 

DB트랜잭션을 사용해야될 사항이 많이 생깁니다.

 

DB트랜잭션이 필요한 대표적 사례는 ATM기기 입니다.

 

 

A사용자가 은행에서 돈을 인출하다가 돈은 인출되었는데, 시스템 전상에 문제가 생겨 뻑이나서

시스템을 키니 인출한 금액을 DB에 반영하여 삭감하지 못했거나, 인출금액을 받지 못하는 등

상황에서 필요한것이 데이터베이스 트랜잭션 입니다.

(자세한 사항 : http://ko.wikipedia.org/wiki/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98)

 

 

PHP 에서는 기본적으로 AUTO_COMMIT 이 활성화 되어있습니다.

 

mysqli_query 함수를 사용하여 SQL 쿼리를 바로 데이터베이스에 반영하게 됩니다.

 

DB트랜잭션을 사용하기 위해서는 우선 AUTO_COMMIT 를 비활성화 시켜야 합니다.

 

그래야 mysqli_query 쿼리를 날려도 데이터베이스에 반영되지 않습니다.

 

즉, DB트랜잭션의 처리 순서는 아래와 같습니다.

1. mysqli_autocommit 함수를 통해 autocommit 비활성화(false)

2. insert, delete 작업 등

3. 만약 실패시 mysqli_rollback 함수를 통해 데이터 롤백

4. 최종 성공시 mysqli_commit (수동 커밋)

5. mysqli_autocommit 함수를 통해 autocommit 활성화(true)

 

아래 예제코드를 통해 DB트랜잭션의 처리를 보여드리겠습니다.

 

조건) 사용자 테이블에 사용자 정보를 입력함과 동시에 반드시 카테고리, 사용자의 이미지 패스를 저장해야 한다.

여기서, 카테고리 및 사용자 이미지패스를 저장할때 한번이라도 실패하는 경우 치명적 시스템 손실을

유발하기 때문에 단 하나라도 실패시 데이터를 롤백되어 데이터베이스에 반영되지 않는다.

 

class Database {
	
	private $host_name = "localhost";
	private $host_id = "root";
	private $host_password = "root";
	private $db_name = "test";
	private $conn;

	private function __construct() {
		$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() {
		$id = mysqli_insert_id($this->conn);
		return $id;
	}

	public function addMember($user_id, $title, $context, $thumbnail_path, $image_path, $category) {
		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' 카테고리의 다른 글

연결 커넥션에서 INSERT 한 마지막 ID값 구하기  (0) 2014.06.25
CR Administrator 제작중  (0) 2012.01.21