💡트랜잭션
트랜잭션(Transaction)은 데이터를 조작하는 업무의 물리적(시간적) 단위(행동의 범위)를 말한다.
1개 이상의 명령어를 묶어 놓은 단위이다.
트랜잭션이 중요한 이유는 다른 명령어는 실수를 해도 그 영향이 크지 않은데, 여기에 속한 명령어들은 실수했을 때 손해가 크기 때문이다.
트랜잭션 관련 명령어, DCL(TCL)
1. COMMIT
2. ROLLBACK
3. SAVEPOINT
💡트랜잭션이란?
내가 역삼은행에 200억이 있는데, 부산에서 건물을 사려고 한다고 가정하자.
그러면 다음과 같은 일련의 과정이 실행될 것이다.
- 부산은행에 방문한다.
- 부산은행에 돈을 인출해 달라고 신청한다.
- 부산은행에서 역삼은행에 이 사람이 건물을 살 200억이 있는지 확인을 요청한다.
- 역삼은행에서 200억을 인출하여 부산은행에 준다.
- 200억으로 부산건물을 구매한다.
아앗!!🌩️😲 역삼은행에서 200억을 차감하는 과정에서 번개가 서버에 내리쳐 200억이 차감되지 않았다고 하자.
이렇게 문제가 발생했을 때, 복구하는 깔끔한 방법은 1번부터 없었던 일로 하는 것이다.
지금처럼 하나의 작업이 실패하는 순간 이후의 작업에 영향을 미치기 때문에 앞서 일어난 과거의 일들을 초기화시키는 걸 DB에서는 가장 좋은 해결책으로 여긴다.
그리고 이러한 시간별로 일어나는 업무들의 집합을 트랜잭션이라고 한다.
💡트랜잭션 관리 명령어
로그인 직후에(접속) 트랜잭션이 시작되었다고 표현한다.
트랜잭션은 모든 명령어를 기억하지 않으며, 데이터베이스에 영향을 미칠 수 있는 작업만을 기억한다.
트랜잭션으로 관리되는 명령어는 INSERT, UPDATE, DELETE 명령어이다.
INSERT, UPDATE, DELETE 작업은 오라클에 적용되지 않고, 임시 메모리에 적용된다.
DELETE FROM tblTrans WHERE name = '박문수'; --트랜잭션에 포함
SELECT * FROM tblTrans; --트랜잭션과 무관
테이블을 출력하니 '박문수' 데이터가 사라진 것을 볼 수 있다.
이 삭제 작업은 트랜잭션에 저장되며, 아직 진짜 Oracle DB에는 적용되지 않은 상태이다.
ROLLBACK
ROLLBACK;
ROLLBACK은 현재 트랜잭션에서 했던 모든 행동을 데이터베이스에 적용하지 않고 취소하는 명령어이다.
COMMIT
DELETE FROM tblTrans WHERE name = '박문수';
COMMIT;
COMMIT은 현재 트랜잭션에서 했던 모든 행동을 데이터베이스에 적용하는 명령어이다.
COMMIT을 하면 '박문수' 데이터가 완전히 삭제된다.
우리가 하는 행동을 시간순으로 기억할 수 있도록 해야 한다. 언제부터 트랜잭션이 시작되었는지를 기억해야 데이터를 되돌릴 수 있기 때문이다.
ROLLBACK과 COMMIT을 하는 주기는 스스로 판단하면 된다.
SAVEPOINT
작업 1, 작업 2, 작업 3이 있는데, 작업 3이 잘못되었다고 해서 rollback으로 하나만 바꿀 수 없다. 트랜잭션은 전체로 관리되기 때문이다.
그래서 트랜잭션을 잘게 쪼개서 트랜잭션을 관리하는 savepoint를 사용한다. savepoint를 이용하면 트랜잭션에서 돌아갈 위치를 지정해 줄 수 있다.
savepoint 생성
INSERT INTO tblTrans VALUES ('후후후', '기획부', '직원');
SAVEPOINT a;
DELETE FROM tblTrans WHERE name = '김신애';
SAVEPOINT b;
UPDATE tblTrans SET buseo = '개발부' WHERE name = '후후후';
insert 작업 뒤에 savepoint a를 만들고, delete 작업 뒤에 savepoint b를 만들었다.
savepoint를 걸어 두었기 때문에 rollback을 어디로 할지에 대한 추가 선택지가 생겼다.
rollback to savepoint
ROLLBACK TO b;
b로 rollback을 하자 '후후후' 직원의 부서를 '개발부'로 이동하기 전으로 돌아갔다.
ROLLBACK TO a;
a로 rollback을 하자 '김신애' 직원의 데이터가 삭제되기 전으로 돌아간다.
💡다른 DBMS tool 사용
DELETE FROM tblTrans WHERE name = '김말자';
DBeaver
SQL Developer
DBeaver에서 '김말자' 데이터를 삭제하였다.
DBeaver에서는 '김말자' 데이터가 삭제되어 있는 것으로 보이지만, SQL Developer에서는 '김말자' 데이터가 유지되어 있는 것을 확인할 수 있다.
이는 COMMIT을 하지 않아서 생기는 동기화 문제이다. Oracle은 DBeaver를 사용하는 사람과 SQL Developer를 사용하는 사람을 별개의 사용자로 인식한다.
트랜잭션 작업은 내가 하는 행동에 확신이 있을 때 하는 것이다. 특히 협업을 할 때에는 트랜잭션 관리에 더욱 신경쓰도록 한다.
💡트랜잭션의 시작과 끝
새로운 트랜잭션이 시작하는 시점
1. 클라이언트 접속 직후
2. commit 실행 직후
3. rollback 실행 직후
현재 트랜잭션이 종료되는 시점
1. commit
2. rollback
3. 클라이언트 접속 종료
4. DDL 실행
commit
현재 트랜잭션을 종료 + DB에 반영
rollback
현재 트랜잭션을 종료 + DB에 반영 안 함
클라이언트 접속 종료
a. 정상 종료: 현재 트랜잭션에 아직 반영이 안 된 명령어가 남아있으므로 사용자에게 어떻게 할지 질문한다. 이때 commit, rollback을 선택할 수 있다.
b. 비정상 종료: 메모리 상(트랜잭션)의 모든 작업이 반영이 될 만한 틈이 없이 강제 종료된다. 즉, rollback이 된다고 생각하면 된다.🌩️
DDL 실행
CREATE, ALTER, DROP을 실행하면 즉시 commit이 실행된다. DDL은 구조를 변경하기 때문에 그 안에 들어 있는 데이터에 영향을 끼쳐서 사전에 미리 저장(commit)되는 것이다.
UPDATE tblTrans SET jikwi = '사장' WHERE name = '김신애';
-- 시퀀스 객체 생성
CREATE SEQUENCE seqTrans; -- 현재 트랜잭션 COMMIT 동반
ROLLBACK;
SELECT * FROM tblTrans;
시퀀스 객체를 생성하는 순간 현재 트랜잭션이 commit이 되기 때문에 rollback이 되지 않는다.
자동으로 commit이 실행되는 것을 인지하여 CREATE, ALTER, DROP를 조심해서 사용하도록 한다.