
트랜잭션은 데이터베이스의 논리적 연산단위입니다. 밀접히 관련돼 분리할 수 없는 한 개 이상의 데이터베이스 조작을 말합니다. 하나의 트랜잭션에는 하나 이상의 SQL 문장이 포함됩니다. 트랜잭션은 더이상 분리할 수 없기 때문에 전부 적용하거나 전부 취소해야합니다. 이런 관점에서 데이터베이스 응용 프르로그램은 트랜잭션의 집합으로 정의할 수있습니다.
트랜잭션의 특성
- 원자성 : 트랜잭션에서 정의된 연산들은 모두 성공적으로 실행되던지 아니면 전혀 실행되지 않은 상태로 남아있어야합니다.
- 일관성 : 트랜잭션 실행 전의 데이터베이스에 오류가 없다면 트랜잭션 실행 이후에도 오류가 없어야합니다.
- 고립성 : 트랜잭션이 실행되는 도중에 다른 트랜잭션의 영향을 받아 잘못된 결과를 만들어서는 안됩니다.
- 지속성: 트랜잭션이 성공적으로 수행되면, 트랜잭션이 갱신한 데이터베이스의 내용은 영구적으로 저장됩니다.
트랜잭션 LOCK
트랜잭션의 원자성을 충족하기위해 데이터베이스는 다양한 레벨의 잠금기능(LOCK)을 제공합니다. 잠금은 기본적으로 트랜잭션이 수행하는 동안 특정 데이터에 대해서 다른 트랜잭션이 동시에 접근하지 못하도록 제한하는 기법입니다. 잠금이 걸린 데이터는 잠금을 실행한 트랜잭션만 독점적으로 접근할 수 있고, 다른 트랜잭션으로부터 간섭이나 방해를 받지 않는 것이 보장됩니다. 잠금이 걸린 데이터는 잠금을 수행한 트랜잭션만 해제할 수 있습니다.
COMMIT
입력, 수정, 삭제한 데이터에 대해 전혀 문제가 없다고 판단되면 COMMIT 명령어로 트랜잭션을 완료합니다. COMMIT 이전의 데이터 상태는 다음과 같습니다.
- 데이터 변경을 취소해 이전 상태로 복구가능.
- 현재 사용자는 SELECT 문장으로 결과를 확인가능.
- 다른 사용자는 현재 사용자가 수행한 명령의 결과를 확인불가.
- 변경된 행은 잠금이 설정돼서 다른 사용자가 변경불가.
테이블에 데이터를 입력하고 COMMIT을 실행합니다.
INSERT
INTO PLAYER (PLAYER_ID, TEAM_ID, PLAYER_NAME, POSITION, HEIGHT, WEIGHT, BACK_NO)
VALUE('1997035', 'K02', '이운재', 'GK', 182, 82 1);
COMMIT;
테이블에 있는 데이터를 수정하고 COMMIT을 실행한다.
UPDATE PLAYER SET HEIGHT = 100;
COMMIT;
테이블에 잇는 데이터를 삭제하고 COMMIT을 실행한다.
DELETE FROM PLAYER;
COMMIT;
COMMIT 이후의 데이터 상태는 다음과 같다.
- 데이터에 대한 변경 사항이 데이터베이스에 반영
- 이전 데이터는 영구 삭제
- 모든 사용자가 결과확인 가능
- 관련 행에 대한 잠금이 풀리고, 다른 사용자들이 행 조작 가능
ROLLBACK
테이블 내 입력한 데이터나 수정한 데이터, 삭제한 데이터에 대해 COMMIT 이전에는 변경사항을 취소할 수 있습니다. 데이터베이스에서는 ROLLBACK 기능을 사용합니다. 롤백은 데이터 변경이 취소돼 데이터가 이전 상태로 복구되며, 관련 행에 대한 잠금이 풀리고 다른 사용자들이 데이터 변경을 할 수 있게됩니다.
테이블에 데이터를 입력하고 ROLLBACK을 실행한다.
INSERT
INTO PLAYER (PLAYER_ID, TEAM_ID, PLAYER_NAME, POSITION, HEIGHT, WEIGHT, BACK_NO)
VALUE('1997035', 'K02', '이운재', 'GK', 182, 82 1);
ROLLBACK;
-- PLAYER 테이블에 있는 데이터를 수정하고 ROLLBACK 실행한다.
UPDATE PLAYER SET HEIGHT = 100;
ROLLBACK;
-- PLAYER 테이블에 잇는 데이터를 삭제하고 ROLLBACK 실행한다.
DELETE FROM PLAYER;
ROLLBACK;
ROLLBACK 후의 데이터 상태는 다음과 같습니다.
- 데이터에 대한 변경 사항은 취소
- 데이터가 트랜잭션 시작 이전의 상태로 되돌려집니다.
- 관련 행에 대한 잠금이 풀리고 다른 사용자들이 행을 조작할 수 있습니다.
COMMIT과 ROLLBACK 을 통해 다음과 같은 효과를 볼 수 있습니다.
- 데이터 무결성
- 영구적인 변경을 하기 전에 데이터의 변경 사항 확인 가능.
- 논리적으로 연관된 작업을 그룹핑해 처리.
SAVEPOINT
SAVEPOINT를 정의하면 ROLLBACK 할 때 트랜잭션에 포함된 전체 작업을 롤백하는 것이 아니라, 현 시점에서 SAVEPOINT까지 트랜잭션의 일부만 롤백할 수 있습니다. 따라서 대규모 트랜잭션에서 에러가 발생했을 때 SAVEPOINT 까지의 트랜잭션만 롤백하고 실패한 부분에 대해서만 다시 실행할 수 있습니다. 복수의 저장점을 지정할 수 있으며, 동일이름으로 여러 개의 저장점을 저장했을 때는 마지막에 정의한 SAVEPOINT 만 유효합니다.
SAVEPOINT SVPT1;
SAVEPOINT까지 롤백할 때는 ROLLBACK 뒤에 SAVEPOINT명을 지정합니다. 저장점 설정 이후에 있었던 데이터 변경에 대해서만 원래 데이터 상태로 되돌아가게 한다.
ROLLBACK TO SVPT1;
SAVEPOINT를 지정하고, 테이블에 데이터를 입력한 다음 롤백을 이전에 설정한 저장점까지 실행합니다.
SAVEPOINT SVPT1;
INSERT
INTO PLAYER (PLAYER_ID, TEAM_ID, PLAYER_NAME, POSITION, HEIGHT, WEIGHT, BACK_NO)
VALUE('1997035', 'K02', '이운재', 'GK', 182, 82 1);
ROLLBACK TO SVPT1;
SAVEPOINT를 지정하고 테이블에 있는 데이터를 수정한 다음 롤백을 이전에 설정한 지점까지 실행합니다.
SAVEPOINT SVPT2;
UPDATE PLAYER SET HEIGHT = 100;
ROLLBACK TO SVPT2;
SAVEPOINT를 지정하고 테이블에 있는 데이터를 삭제한 다음 롤백을 이전에 설정한 지점까지 실행합니다.
SAVEPOINT SVPT3;
DELETE FROM PLAYER;
ROLLBACK TO SVPT3;
새로운 트랜잭션을 시작하기 전에 PLAYER 테이블의 데이터 건수와 몸무게가 100인 선수의 데이터 건수를 확인합니다.
SELECT COUNT (*) AS CNT FROM PLAYER; -- 480
SELECT COUNT (*) AS CNT FROM PLAYER WHERE WEIGHT = 100; -- 0
새로운 트랜잭션을 시작합니다.
INSERT
INTO PLAYER (PLAYER_ID, TEAM_ID, PLAYER_NAME, POSITION, HEIGHT, WEIGHT, BACK_NO)
VALUE('1997035', 'K02', '이운재', 'GK', 182, 82 1);
SAVEPOINT SVPT_A;
UPDATE PLAYER SET WEIGHT = 100
SAVEPOINT SVPT_B;
DELETE FROM PLAYER;
SAVEPOINT B 저장점까지 롤백을 수행하고 롤백 전후 데이터를 확인합니다.
SELECT COUNT (*) AS CNT FROM PLAYER; -- 0
ROLLBACK TO SVPT_B;
SELECT COUNT (*) AS CNT FROM PLAYER; -- 481
SAVEPOINT A 저장점까지 롤백을 수행하고 롤백 전후 데이터를 확인해봅니다.
ROLLBACK TO SVPT_A;
SELECT COUNT (*) AS CNT FROM PLAYER WHERE WEIGHT = 100; -- 0
트랜잭션 최초 시점까지 롤백을 수행하고 롤백 전후 데이터를 확인해본다.
ROLLBACK;
SELECT COUNT (*) AS CNT FROM PLAYER; -- 480
해당 테이블에 데이터의 변경을 발생시키는 입력, 수정, 삭제 명령어 수행 시 변경되는 데이터의 무결성을 보장하는 것이 커밋과 롤백의 목적입니다. 커밋은 '변경된 데이터를 테이블이 영구적으로 반영해라' 라는 의미이고, 롤백은 변경된 데이터가 문제가 있으니 변경사항을 취소하고 이전의 데이터로 복구하라는 의미입니다.
SAVEPOINT/SAVE TANSACTION은 데이터 변경을 사전이 지정한 저장점까지만 롤백하라는 의미입니다. ORACLE의 트랜잭션은 트랜잭션의 대상이 되는 SQL 문장을 실행하면 자동으로 시작되고, COMMIT 또는 롤백을 실행한 시점에서 종료됩니다. 단, 다음의 경우에는 COMMIT과 ROLLBACK을 실행하지 않아도 자동으로 트랜잭션이 종료됩니다.
- CREATE, ALTER, DROP, RENAME, TRUNCATE TABLE 등 DDL 문장을 실행하면, 그 전후 시점에 자동으로 커밋이 수행된다.
- DML 문장 이후 명시적인 커밋이 없더라도 DDL 문장이 실행되면 데이터의 변경 사항이 자동으로 커밋된다.
- 데이터베이스를 정상적으로 접속 종료하면 자동으로 트랜잭션이 커밋된다.
- 애플리케이션의 이상 종료로 데이터베이스와의 접속이 단절되면 트랜잭션이 자동으로 롤백된다.