Programming/SQL

트랜젝션(transaction), commit, rollback 2021-06-21

최동훈1 2021. 6. 21. 15:40

 오라클에서 한 세션에서 INSERT 한 데이터가 왜 다른 세션으로 접속했을때, 반영이 되지 않는 것일까?

이 질문에 답을 하기 위해선, 트랜젝션이 무엇인지 알아야한다.

내가 오늘 공부하며 내린 결론은 트랜잭션이란

DB의 변화를 가져오는 일련의 "명령어들"의 단위집합

이다. 좀더 쉽게 풀어쓰면, 한 업무의 수행단위 라 볼수 있다. 자세히 설명하자면, 계좌이체 라는 과정을 수행하려 했을때, 한 계좌에서 돈을 UPDATE를 통해 빼주고, 다른 계좌에서 UPDATE를 통해 돈을 더해줘야만, "계좌이체"라는 하나의 업무단위(트랜잭션)가 완성되는 것이다. 즉, UPDATE/INSERT/DELETE 각각의 명령어 한개가 수행되었다고 해서 트랜젝션이 완료되는 것이 아니라(물론 하나의 명령어로 완료되는 트랜잭션이 있을수도 있다.) 목표한 모든 과정을 이루어지게 만드는 "명령어들의 집합" 이 수행되었을 경우에면, 트랜잭션이 완료되는 것이다.

그렇다면, 한 세션에서 트랜잭션을 완료했는지 안했는지의 기준은 무엇이될까? 즉, 명령어 한개 실행했다고 완료될수도 있고, 아니면, 복잡한 기능을 구현하기 위해서 더 많은 명령어를 해야할수도 있다.

 여기서 commit과 rollback의 필요성이 나온다. 우선 트랜잭션이 완성됬는지 안되었는지의 기준은 commit이나 rollback명령어가 실행됬는지 안됬는지 이다. commit이 실행된다면, DBMS의 모든 세션이 접근 가능한 영구 저장 테이블 스페이스에 각 세션의 임시 저장소에서 수행된 일련의 명령어들이 반영된다.

 

*오라클은 테이블을 만들때, 각 세션별로 테스트해볼 수 있는 임시저장 테이블스페이스 와 모든 세션이 공유하는 영구 저장 스페이스를 따로 만든다. 

임시저장 스페이스와 영구저장 스페이스와의 관계

또한 문제가 있다. 우선 어떤 데이터를 변경하려고 테스트 중일때( 그 명령어가 DB client 에 의해서 '실행' 되어서 한쪽의 세션의 임시저장 스페이스에만 저장되었을때, 아직 commit이나 rollback 명령하기전)는 같은 데이터를 다른 세션에서 접근 못하도록 ROCK을 걸어 버린다. 그리고 마침내 테스트하던 세션에서 commit이나, rollback을 하게되면 UNLOCK 상태가 되어 다른 세션에서도 자유롭게 해당 데이터를 테스트할수 있도록 된다.

코드로서 예를 들어 보겠다.

session1

INSERT INTO MEMBER id,pwd,name VALUES='abc','111','최동훈';
commit;--commit 하는 순간 임시저장소에 저장되있던 최동훈 레코드가 영구 저장소로 저장됨.

UPDATE SET MEMBER pwd='222' WHERE name='최동훈';--여기까지 실행.
--아직 UPDATE 명령어는 commit 안했으므로,  LOCK 상태.

session2

UPDATE SET MEMBER pwd='777' WHERE id='최동훈';--ROCK걸려서 실행 자체가 안됨. 테스트도 못함.
--ROCK 상태를 벗어날려면 Session1에서 해당 트랜젝션을 끝내줘야함.