작업의 완전성을 보장하기 위해서 여러개의 작업을 하나의 작업 단위로 그룹화하여 처리하는 것이다.
하나의 작업 단위로 묶었기에 실행하는 작업들 중 하나라도 실패하면 해당 작업내에 모든 작업이 실패하게 된다.
자주하는 게임 중에서 LOL로 생각을 해보기로 했다.
현재 유행하는 아이템 중에 하나인 몰왕의 검을 샀다고 치자.
이 몰왕의 검을 상점을 열어서 눌렀을 때,
- 아이템 상점 DB에 등록된 몰왕의 검 정보를 불러와서 현재 이걸 산 사람의 돈이 몰왕의 검을 살 수 있는지 체크를 한다.
- 살 돈이 모여있다면 해당 아이템을 캐릭터의 아이템 창 DB에 추가하며 캐릭터가 가진 돈을 감소 시킨다.
- 해당 아이템의 스텟(공격력, 공격 속도, 생명력 흡수) 등을 업데이트를 한다.
이 중에서 만약 3번 작업이 안됬다고 쳐보자.
그렇게 되면 아이템을 사더라도 캐릭터에 스텟이 추가되지 않았음으로 아이템창만 잡아먹는 깡통이 될 것이다.
이걸 방지하기 위해서 트랜잭션을 사용하여 해당 작업들(1,2,3) 중 하나라도 실패한다면 DB들을 원래 상태로 돌리고 다시 작업하는 것이다
이런 트랜잭션에도 문제가 생길 때가 있는데 그것은 하나의 DB에 있는 정보에 여러 트랜잭션이 접근할 때이다.
몰왕의 검을 예시로 계속 들어보도록 하자.
A 트랜잭션
1. 몰왕의 검을 사서 스텟을 적용 받았다.
B 트랜잭션
1. 몰왕의 검을 팔았다.
2. 스텟을 갱신하고 되팔았을 때 버는 돈을 받았다.
정말 이렇게 처리할 리는 없겠지만
라고 생각을 해봤을 때 이중에서 A 트랜잭션에서 에러가 발생해서 몰왕의 검을 사지 못했고 스텟을 적용받지 못했다고 생각을 해보자.
그렇다면 B트랜잭션만 적용을 받게 되어 몰왕을 파는 돈이 들어오며 몰왕의 검의 스텟만큼 캐릭터의 스텟이 깎이게되는 말도 안되는 일이 일어날 것이다.
이런 것이 바로 동시성,
다수의 사용자가 동일한 시스템을 공유하면서 발생하는 동시 접근 문제(동시성 문제)이다.
그럼 이런 문제를 해결하기 위해서는 어떻게 해야할까?
데이터 베이스의 테이블이나 테이블의 행에 락을 걸어서 다른 사용자가 작업중인 테이블에 접근하지 못하도록 하는 방법이 있다.
그렇지만 이렇게 락을 걸어서 접근하지 못하도록 할 때 교착 상태의 현상이 발생할 수 있는데,
교착상태는 여러 테이블에 락을 적용했을 때, 다른 작업이 처리되지 못하게 점유하고 있는 작업이 있을 때 , 다른 작업이 끝나는 것을 무제한으로 기다리는 것을 의미한다.
이런 교착상태를 막기 위해서는 적재적소에 필요한 락의 수준을 설정하여 트랜잭션을 구성해야만 한다.
여러 트랜잭션이 동시에 처리될 때 다른 트랜잭션에서 변경 및 조회하는 데이터를 읽을 수 있도록 허용하거나 거부하는 것을 결정하는 것이다.