
사용자가 애플리케이션 서버나 데이터베이스 접근 툴을 사용해서 데이터베이스 서버에 연결 요청을 하고 커넥션을 맺게 된다. 이때 데이터베이스 서버는 내부에 세션 을 만든다.
커넥션과 세션은 1:1 로 매핑되는듯 하다.
commit or rollback 을 통해 트랜잭션을 종료하면 이후에 새로운 트랜잭션을 다시 시작 가능트랜잭션에 관한 예제들은 READ COMMITED(커밋된 읽기) 트랜잭션 격리 수준으로 설정되어 있는 상황입니다.
- 데이터 변경 쿼리를 실행하고 데이터베이스에 결과를 반영하려면
commit을 호출하고, 반영하고 싶지 않다면rollback을 호출commit호출 전까지는 임시로 데이터를 저장하여 해당 트랜잭션을 시작한 세션에게만 변경 데이터가 보이고 다른 세션은 볼 수 없음 -> 만약READ UNCOMMITED(커밋되지 않은 읽기)가 트랜잭션 격리 수준으로 설정되어 있다면 볼 수 있다.

세션1 이 트랜잭션을 시작하고 신규 회원1, 신규 회원2를 데이터베이스에 추가(아직 커밋하지 않음)세션1 만 조회 가능세션2 가 select 쿼리를 실행해도 임시 상태의 신규 데이터 조회 불가능//트랜잭션 시작
set autocommit false; //수동 커밋 모드
insert into member(member_id, money) values ('newId1',10000);
insert into member(member_id, money) values ('newId2',10000);


왼쪽이 세션1 오른쪽이 세션2 이다. 실제 h2 데이터베이스에서 확인한 결과 commit 실행을 하지 않아 세션1 에서만 조회가 가능하고 세션2 에서는 조회할 수 없다.
위 상황을 예로 들자면 세션2 가 신규 데이터 조회가 가능하여 조회한 후 해당 데이터로 어떠한 로직을 수행할 수 있다. 이때 세션1 이 rollback 을 수행한다면 신규 데이터는 데이터베이스에 반영되지 않아 데이터 정합성에 문제가 발생한다. 즉, commit 전의 데이터를 조회할 수 있다면 rollback 이 실행됐을 때 문제가 발생하므로 commit 전의 데이터는 다른 세션에서 보이지 않아야 한다.

세션1 이 신규 데이터를 추가하고 commit 호출임시 -> 완료 로 변경commit 이 완료됐으므로 세션2 에서도 신규 데이터 조회 가능// 커밋 실행
commit;

commit 을 호출하면 신규 데이터가 데이터베이스에 반영되어 세션2 에서도 조회가 가능한 것을 볼 수 있다.

세션1 에서 신규 데이터를 추가한 다음 rollback 을 호출세션1 이 데이터베이스에 반영한 모든 데이터가 처음 상태로 원상 복구rollback 이 호출되면 트랜잭션 시작 직전의 상태로 복구//트랜잭션 시작
set autocommit false; //수동 커밋 모드
insert into member(member_id, money) values ('newId1',10000);
insert into member(member_id, money) values ('newId2',10000);
위 SQL을 실행하면 세션1 에서는 신규 데이터 조회가 가능하다.

// 롤백 실행
rollback;
하지만 rollback 을 호출하게 되면 데이터베이스에 반영이 되지 않는다.
현재 데이터베이스에는 memberA 10000원 memberB 10000원의 데이터가 들어있다.
set autocommit false;
update member set money=10000 - 2000 where member_id = 'memberA';
update member set money=10000 + 2000 where member_id = 'memberB';
memberA 가 memberB 에게 2000원을 이체하는 상황이다.

commit 호출 전이므로 memberA 에게는 변경된 데이터가 보이지만 memberB 는 원래 데이터가 조회된다.
commit;
이때 commit 을 호출하게 되면 memberB 의 세션에서도 memberA 의 잔액이 8000원으로 감소, memberB 의 잔액이 12000원으로 증가한 것을 볼 수 있다.
set autocommit false;
update member set money=10000 - 2000 where member_id = 'memberA'; //성공
update member set money=10000 + 2000 where member_iddd = 'memberB'; //예외
해당 쿼리를 실행하면 컬럼을 찾을 수 없다는 오류로 memberA 의 잔액은 2000원 감소하지만, memberB 의 잔액은 증가하지 못하고 유지된다.

commit;

이 상태에서 commit 을 호출하면 memberA 의 잔액만 줄어드는 심각한 문제가 발생한다. 즉, 이러한 문제가 발생한다면 commit 을 호출하면 안된다. rollback 을 호출하여 데이터를 트랜잭션 시작 시점으로 원상 복구해야 한다.
위에서 발생한 예외 상황에서 이번에는 rollback 을 호출해보겠다.
rollback;

rollback 을 호출하면 계좌이체 실행하기 전 상태 즉, 데이터가 트랜잭션 시작 시점으로 원상 복구 되는 것을 확인할 수 있다.
원자성
트랙잭션 내에서 실행하는 작업들은 마치 하나의 작업처럼 모두 성공 모두 실패 해야 한다. 트랜잭션의 원자성 덕분에 여러 SQL 명령어를 마치 하나의 작업처럼 처리할 수 있다.
자동 커밋
데이터베이스는 기본 설정이 자동 커밋이기 때문에 하나의 쿼리가 완료되면 commit 이 호출된다. 수동 커밋 모드를 사용해야 중간에 실패해도 rollback 을 호출하여 원상 복구 시킬 수 있다. 자동 커밋에서 수동 커밋으로 전환 하는 것을 트랜잭션을 시작한다고 표현한다.