데이터베이스에서 모든 변경사항을 제대로 관리하고 싶으면 PostgreSQL은 트랜잭션이라는 개념을 써. 이건 여러 SQL 작업을 하나의 묶음으로 처리하는 거야. 뭔가 잘못되면 변경사항을 취소해야 해. 이럴 때 BEGIN, COMMIT, ROLLBACK 명령어가 등장하지.
트랜잭션 명령어는 그냥 형식적인 게 아니라, 데이터가 오류나 장애로부터 안전하게 지켜지도록 핵심 역할을 해. 여러 SQL 작업을 연달아 할 때, 뭔가 하나라도 실패하면 전체를 원래대로 돌려야 하잖아. 이게 바로 트랜잭션 명령어가 필요한 이유 중 하나야 — 데이터 일관성을 지키는 데 도움을 주거든.
그리고 트랜잭션은 이른바 원자성(atomicity)도 보장해: 모든 변경이 한꺼번에 적용되거나, 아예 아무것도 적용되지 않아. 그래서 데이터베이스가 '반쯤'만 업데이트되는 상황이 없어 — 예를 들어 돈은 빠졌는데 상품은 주문에 안 들어간다든지 하는 일 말이야.
또 트랜잭션 덕분에 유연하게 작업할 수 있어. 복잡한 작업 흐름도 만들 수 있고, 언제 COMMIT으로 확정할지, ROLLBACK으로 취소할지 직접 컨트롤할 수 있지. SAVEPOINT로 중간에 부분 취소도 가능하고. 이런 게 데이터베이스 작업을 안전하면서도 관리하기 쉽게 만들어줘.
BEGIN 명령어
BEGIN 명령어는 PostgreSQL에게 트랜잭션을 시작한다고 알려주는 거야. 이걸 실행하면 이후의 모든 변경사항이 COMMIT으로 확정하거나 ROLLBACK으로 취소하기 전까지 '보류' 상태로 남아.
예를 들어, 계좌에서 100 단위의 돈을 다른 계좌로 옮기고 싶다고 해보자. BEGIN으로 트랜잭션을 시작해:
BEGIN;
-- 트랜잭션 시작함
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- 계좌 1의 잔액을 100만큼 줄임
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- 계좌 2의 잔액을 100만큼 늘림
트랜잭션 안에서 명령어를 실행하는 동안, 다른 데이터베이스 사용자들은 네 변경사항을 볼 수 없어. COMMIT을 해야만 보이게 돼.
COMMIT 명령어
COMMIT 명령어는 트랜잭션을 끝내고, 그 안에서 한 모든 변경사항을 데이터베이스에 저장해. 이 명령을 실행하면 모든 사용자가 변경사항을 볼 수 있어.
트랜잭션을 마무리하는 예시:
COMMIT;
-- 트랜잭션의 모든 변경사항이 저장됨
이제 위 예시에서 바꾼 잔액이 '영구적'으로 남아. 돈이 제대로 옮겨진 거지.
ROLLBACK 명령어
트랜잭션을 하다가 실수했거나 변경을 취소하고 싶으면 ROLLBACK 명령어를 쓰면 돼. 이 명령은 BEGIN 이후에 한 모든 작업을 취소해.
예를 들어, 돈을 옮기다가 계좌에 돈이 부족하다는 걸 알게 됐다고 해. 그럼 트랜잭션을 취소하지:
BEGIN;
-- 트랜잭션 시작함
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- 어, 실수: 잔액이 부족함.
ROLLBACK;
-- 모든 변경사항이 취소되고, 데이터베이스가 원래 상태로 돌아감
ROLLBACK을 하면 데이터베이스에 아무런 변경도 남지 않아. 실수 방지에 진짜 유용하지.
전체 예시: 계좌 간 돈 이체
이제 다 합쳐보자. 잔액 확인, 돈 이체, 오류 시 취소까지 포함된 트랜잭션 전체 예시야:
BEGIN;
-- 트랜잭션 시작
-- 계좌 잔액 확인
SELECT balance INTO current_balance FROM accounts WHERE account_id = 1;
-- 잔액이 충분한지 확인
IF current_balance >= 100 THEN
-- 충분하면 이체 실행
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
-- 변경사항 확정
ELSE
-- 부족하면 트랜잭션 취소
ROLLBACK;
END IF;
이 예시는 트랜잭션 명령어들이 데이터 불일치를 막기 위해 어떻게 함께 동작하는지 보여줘.
IF THEN ELSE END IF — 이건 저장 프로시저에서 쓰는 구문이고, 몇 단계 뒤에 자세히 다룰 거야:P
오토커밋(autocommit) 설정의 특징
PostgreSQL은 기본적으로 오토커밋 모드가 켜져 있어서, 명시적으로 트랜잭션을 시작하지 않으면 명령어가 바로바로 데이터베이스에 저장돼. 예를 들어:
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- COMMIT 없이도 변경사항이 바로 저장됨
트랜잭션을 직접 관리하고 싶으면 항상 BEGIN으로 명시적으로 트랜잭션을 시작하는 게 좋아.
현재 세션에서 오토커밋을 끄고 싶으면 이렇게 하면 돼:
SET AUTOCOMMIT TO OFF;
기억해: 오토커밋을 끄면, 매 세션마다 COMMIT이나 ROLLBACK으로 마무리해야 해.
트랜잭션 작업에서 흔한 실수들
COMMIT 빼먹기. COMMIT을 깜빡하면, 변경사항이 미완성 상태로 남고 세션이 끝나면 다 사라져.
락(lock) 문제. 트랜잭션이 끝나기 전까지, 그 트랜잭션이 쓰는 리소스가 잠겨 있을 수 있어. 이러면 데이터에 동시에 접근하는 데 문제가 생길 수 있지.
불필요한 ROLLBACK. 가끔 개발자들이 너무 조심해서 굳이 필요 없는 트랜잭션까지 취소해. 이러면 다시 계산해야 하고, 데이터베이스에 부담만 늘어나.
방치된 트랜잭션. 트랜잭션을 시작해놓고 COMMIT이나 ROLLBACK을 안 하면, 세션이 멈추고 데이터베이스 리소스가 잠길 수 있어.
실전에서의 활용
개발자나 DBA(데이터베이스 관리자) 면접에서 PostgreSQL 트랜잭션 구현을 물어볼 수 있어. BEGIN, COMMIT, ROLLBACK 명령어를 이해하고 있다는 건, 데이터를 안전하고 효율적으로 다룰 줄 안다는 뜻이야.
실제로 트랜잭션은 신뢰성 있는 시스템을 만들 때 특히 유용해. 예를 들어, 온라인 쇼핑몰 주문 처리나 멤버십 포인트 계산 같은 데서 말이지.
이제 트랜잭션 기본 명령어를 알았으니, 다음엔 SAVEPOINT 사용법이나 격리 수준(isolation level) 같은 더 흥미로운 주제로 넘어가 보자. PostgreSQL은 진짜 끝도 없는 바다니까, 각오해둬.
GO TO FULL VERSION