논리적인 작업 단위를 구성하는 데이터 조작어(DML)의 모음이다. 즉, 어떤 기능을 수행하기 위한 최소 작업 단위이다.
예를 들어 계좌이체 기능을 생각해보자. A계좌의 10만원을 B계좌로 송금하려고 한다. 그렇다면 A계좌와 B계좌의 잔액을 변경하기 위한 UPDATE문이 각각 한번씩 실행되어야 한다. 그런데 데이터 전송 중 오류가 발생하여 첫 번째 A계좌에 대한 UPDATE문이 실행되고 작업이 종료되었다.
결과적으로 A계좌에서는 돈이 빠져나갔지만 B계좌에는 송금이 이루어지지 않은 상태이다. 따라서 이러한 사고를 막기 위해서는 A, B 계좌의 UPDATE문이 모두 수행되던가 혹은 모두 수행되지 않던가 해야 한다.
이를 위해 '트랜잭션'을 사용한다. 특정 작업을 위한 SQL문을 한 세트로 묶어 그것들이 모두 수행되거나 모두 수행되지 않도록 하는 것이다.
COMMIT : 트랜잭션 내의 모든 DML 실행 결과를 데이터베이스에 영구적으로 반영시킨다.
ROLLBACK : 트랜잭션 내의 모든 DML 실행 결과를 데이터베이스 반영을 전부 취소한다.
-- 트랜잭션 자동으로 시작, hong사용자가 22번, 23번 상품을 장바구니에 저장함
INSERT INTO SAMPLE_CART_ITEMS (USER_ID, PRODUCT_NO, ITEM_AMOUNT) VALUES ('hong', 22, 3);
INSERT INTO SAMPLE_CART_ITEMS (USER_ID, PRODUCT_NO, ITEM_AMOUNT) VALUES ('hong', 23, 1);
-- 22번, 23번 상품의 재고수량을 변경
UPDATE SAMPLE_PRODUCTS
SET PRODUCT_STOCK = PRODUCT_STOCK - 3
WHERE PRODUCT_NO = 22;
UPDATE SAMPLE_PRODUCTS
SET PRODUCT_STOCK = PRODUCT_STOCK - 1
WHERE PRODUCT_NO = 23;
-- 트랜잭션 내 모든 DML 작업의 실행결과를 영구적으로 DB에 반영,
-- 트랜잭션 종료와 동시에 트랜잭션 시작
COMMIT;
-- 트랜잭션 내 모든 DML 작업의 실행결과의 DB반영 취소
-- 위에서 실행된 DML작업의 반영은 취소할 수 없다. 다른 트랜잭션의 작업이기 때문이다.
-- 현재 트랜잭션 내에서는 DML작업을 전혀 수행하지 않았기 때문에 취소할 작업이 없다.
-- 트랜잭션 종료와 동시에 트랜잭션 시작
ROLLBACK;
-- 사용자 등록
INSERT INTO SAMPLE_USERS (USER_ID, USER_PASSWORD, USER_NAME, USER_EMAIL)
VALUES ('ahn', 'zxcv2134', '안중근', 'ahn@gmailcom');
-- ahn사용자가 21번 상품을 장바구니에 저장
INSERT INTO SAMPLE_CART_ITEMS (USER_ID, PRODUCT_NO, ITEM_AMOUNT)
VALUES ('ahn', 21, 4);
-- 21번 상품의 재고수량 변경
UPDATE SAMPLE_PRODUCTS
SET PRODUCT_STOCK = PRODUCT_STOCK - 4
WHERE PRODUCT_NO = 21;
-- 이 트랜잭션 내에서 실행된 DML작업의 실행결과의 DB반영을 취소
ROLLBACK;
데이터베이스에서 세션이란 데이터베이스에 접속하여 작업을 수행한 후, 종료하기까지의 기간이다. 그리고 세션이 여러 개라는 말은 특정 데이터베이스에 접속해서 작업하고있는 연결에 여러 개라는 의미이다. 예를 들어, 특정 계정으로 명령 프롬프트창과 sql developer에 각각 접속해 작업한다면 세션은 두 개가 된다.
앞서 다룬 트랜잭션은 특정 작업을 위한 SQL문의 집합이라고 했다. 그리고 COMMIT과 ROLLBACK을 통해 트랜잭션의 시작과 종료를 제어한다. 그렇다면 세션은 데이터베이스의 접속시점부터 종료까지의 기간이므로 하나의 세션은 여러 트랜잭션을 포함한다. 다시 말해 세션이 트랜잭션보다 큰 범위의 개념이다.
그러면 특정 세션에서 데이터를 변경중 일 때 다른 세션에서는 해당 데이터가 어떻게 보일까? 데이터를 다루고 있는 세션에서 COMMIT 혹은 ROLLBACK이 되기 전까지는 본래의 데이터가 출력된다. 이것이 읽기 일관성이다. 예를 들어, 명령 프롬프트에서 특정 테이블의 행을 삭제했다면 이 작업이 COMMIT되기 전까지는 sql developer에서는 삭제되기 전의 데이터가 출력된다.