DB/SQL - Oracle

[SQL] TCL(트랜잭션 제어어) - commit, rollback, checkpoint(=savepoint)

생각많은 프로그래머 2024. 2. 2. 03:05
SQL 종류
1. 데이터를 정의하는 쿼리 - DDL(데이터 정의어) : create, drop, alter, truncate 
2. 데이터를 조작하는 쿼리 - DML(데이터 조작어) : insert, select, update, delete
3. 데이터를 제어하는 쿼리 - DCL(데이터 제어어) : grant, revoke
4. 트랜잭션 제어하는 쿼리 - TCL(트랜잭션 제어어) : commit, rollback, checkpoint

 

데이터 조작 후에는 트랜잭션 처리*를 위해

반드시 commit이나 rollback을 해야 한다.

TCL ? 
: 트랜잭션 제어어(Transaction Control Language)
트랜잭션을 제어한다는 것은 트랜잭션의 결과를 수용하거나
취소하는 것을 말한다.
(비교적 자주 사용되는 commit, rollback 외에도 checkpoint도 있다.)

*checkpoint : 작업거래의 저장 시점 설정(rollback 위치 지정)
= savepoint

DCL과 TCL은 작업 대상이 상이해서 서로 다른 개념으로 구분하지만
제어 기능이라는 공통점이 있기 때문에 TCL이 DCL에 속하는 개념으로 .
분류되기도 한다.


트랜잭션(transaction)

트랜잭션 처리는 데이터베이스에서 데이터의 일관성과 무결성을
유지하기 위한 중요한 개념이다.

트랜잭션은 데이터베이스에서 수행되는 작업의 논리적 단위를 나타내며,
여러 단계의 작업을 하나의 트랜잭션으로 볼 수도 있다.

트랜잭션 처리는 일반적으로 다음과 같은 네 가지 속성을 가진다. 

1. 원자성(Atomicity): 트랜잭션의 모든 작업은 성공적으로 완료되거나 전혀 수행되지 않아야 한다.
즉, 트랜잭션은 "모두 실행되거나 아무것도 실행되지 않아야" 한다.

2. 일관성(Consistency): 트랜잭션이 실행된 후에도 데이터베이스는 일관된 상태를 유지해야 한다.
즉, 트랜잭션 전후에 데이터베이스는 유효한 상태여야 한다.

3. 고립성(Isolation): 한 트랜잭션이 실행 중일 때, 다른 트랜잭션들이 해당 트랜잭션의
연산에 영향을 미치지 않아야 한다. 즉, 각각의 트랜잭션은 독립적으로 실행되는 것처럼 보여야 한다.

4. 지속성(Durability): 한 번 트랜잭션이 완료되고 커밋되면, 해당 트랜잭션에 의한
변경 사항은 영구적으로 데이터베이스에 반영되어야 한다.
즉, 시스템 장애가 발생하더라도 데이터 손실이 발생하지 않아야 합니다.

트랜잭션 처리는 이러한 4가지 속성을 보장하기 위해
데이터베이스 관리 시스템(DBMS)에 의해 제공되는 기능과 알고리즘에 의해 지원된다.

 

commit이나 rollback을 실행하기 전까지 변경된 데이터는

현재 세션에만 볼 수 있고 최종적으로 데이터베이스에 반영된 상태가 아니다.

commit을 실행하면 데이터가 반영되고, 

rollback을 실행하면 변경 이전 상태로 복귀한다.

 

 

데이터 조작어 :  commit, rollback

 

commit 현재 작업상태를 영구 저장한다는 의미이고, 

영구 저장한다는 의미는 commit하기 전으로 돌아갈 수 없다는 뜻이다.

실행하려면 commit; 과 같이 세미콜론만 붙여서 실행한다.

 

rollback 은 '복구'한다는 의미로,

가장 마지막으로 commit한 상태로 돌아간다는 의미이다.

따라서 commit을 실행한 이후에 어떤 작업을 했는데

rollback을 실행하게 되면 도중에 작업한 부분은

반영되지 않고 직전에  commit한 상태로 돌아간다는 뜻이다.

실행하려면 rollback; 과 같이 세미콜론만 붙여서 실행한다.

 

 

여기에도 규칙이 있는데, 

바로 DDL에 해당하는 명령어로 실행한 경우에는

따로 commit을 하지 않아도 자동으로 commit이 된다는 점이다.

 

하지만 DML, 예를 들어 튜플을 삽입(insert)한 경우라면

꼭  commit 을 해주어야  DB 상에 저장된다.

 

추후 DB를 연동하여 사용하는 경우에는 이 부분이 굉장히 중요하다!

예를 들어서 튜플을 삽입했는데  commit을 안하면

java에서 해당 데이터를 DB에서 조회할 때 방금 삽입한 튜플이 조회되지 않는다.

(가끔 commit을 깜빡하고 왜 조회가 안되는 건지 의아해하다가 

역시 컴퓨터는 거짓말을 하지 않지... 하고 조용히 commit을 누르곤 했다.)

 

rollback은 마지막 commit을 한 상태로 다시 돌려놓는 것을 말한다.

DDL이든 DML이든 commit을 실행한 이후  rollback을 실행했다면

마지막 commit을 기준으로 복구된다.

rollback의 역할이 commit을 철회하는 것이 아니라는 점을 꼭 명심해야 한다!

 

만약 테이블을 생성했다가 이를 취소하고 싶어서  rollback을 실행해도 

그 테이블이 삭제되지 않는다는 말이다. 

또한 DML 명령어로 실행된 작업이 있어도 commit을 했다면 

해당 작업이 rollback으로 인해 복구되지 않는다. 

 

하지만 DML 명령어를 통해 실행한 경우 실행 후 commit을 하지 않았고

rollback을 실행하면 DML명령어 이전으로 복구된다.

 

테이블 생성 후 튜플 삽입 예시

 

예시를 보면 aaa라는 테이블을 생성한 후에

총 3개의 튜플을 삽입했다. 

344번, 347번 라인에서 commit을 실행하여 영구저장처리를 했다.

 

350번 라인에서 select문을 실행한 결과 

아래와 같이 테이블에 3개의 튜플이 삽입된 것을 확인할 수 있다.

 

만약 여기서 351번 라인에서 rollback을 실행한다면 어떻게 될까?

 

커밋 후 롤백 처리한 화면

 

rollback을 실행하면 마지막 commit상태로 돌아간다는 의미이므로

맨 마지막 commit을 실행했던 라인인 347번 라인을 기준으로

2번째 튜플이 삽입된 상태로 돌아간다는 의미이다.

351번 라인에서 rollback을 실행 후 

352번 라인에서 테이블 aaa의 전체 튜플을 조회했을 때

튜플이 2개만 조회된다.

 

만약 353번 라인에서 rollback을 실행한다면

344번 라인에서 commit을 한 상태로 돌아갈까?

 

정답은 아니다. 

 

commit을 한다는 것은 영구 저장한다는 의미로,

그 이전으로 돌아갈 수 없다는 의미이기 때문에

rollback을 한 번 더 실행했다고 해서 전전 commit 상태로 

돌아가지 않는다. 그러므로 commit을 신중하게 해야 한다.

 

+

commit과 rollback은 위 화면처럼 직접 입력해서 실행할 수도 있고

아래와 같이 버튼을 클릭해서 실행할 수도 있다.

메뉴 상단에 표시된 부분을 보면 왼쪽이 커밋, 오른쪽이 롤백이다.

버튼 아이콘이 직관적으로 표시되어 있어서 이 둘을 구분하는 것이 그리 어렵지 않다!

커밋과 롤백 아이콘의 위치