1. 낙관적 동시성 제어
--------------------------------------------------------------------------------------------------------------------
사용자들이 동일한 데이터를 동시에 수정하지 않을 것이라 가정한다. 따라서 데이터를 읽을 때는 잠김이 발생하지 않지만
데이터를 수정하는 시점에서는 앞서 읽은 데이터가 다른 사용자에 의해 변경되었는지 반드시 점검해야 한다.
2. 비관적 동시성 제어
--------------------------------------------------------------------------------------------------------------------
사용자들이 동일한 데이터를 동시에 수정할 수 있다고 가정한다. 따라서 한 사용자가 데이터를 읽는 시점에 잠김을 걸고
조회 또는 갱신 처리가 완료될 때까지 이를 유지한다.
FOR UPDATE NOWAIT : Lock이 걸렸다면 대기 없이 Exception을 던짐
FOR UPDATE WAIT 3 : Lock이 걸렸다면 3초간 대기하고 Exception을 던짐
3. 선분이력 동시성 제어 구현 사례
-------------------------------------------------------------------------------------------------------------------- 고객 부가서비스이력 부가서비스 # 고객ID -------------------< # 시작일시 >--------------------- # 부가서비스ID * 고객명 # 종료일시 * 부가서비스명 * 속성1 o 기타이력 속성 * 속성1 * 속성2
첫 번째 트랜잭션이 1을 수행하고 2로 진입하지전에...어떤 이유에서건 두 번째 트랜잭션이 동일 이력에 대해 1~4를 먼저 진행해 버리면 선분 이력이 깨지게 된다.
따라서 트랜잭션이 순차적으로 진행할 수 있도록 직렬화 장치를 마련해야 하는데, 1번 문장수행전에 SELECT FOR UPDATE 문을 이용해 해당 레코드에 잠김을 설정하면 된다.
그런데.....이 경우에도 문제가 있다.
기존 부가 서비스이력에 전혀 존재않았던 고객일 경우 잠김이 걸리지 않게되고 그러면 동시에 두개의 트랜잭션이 3번 INSERT문으로 진입하여,
결과적으로 시작일시는 다르면서 종료일시가 동일한 두개의 이력 레코드가 생기게 된다.
이를 막기 위해서는...
부가서비스 이력의 상위 엔터티인 고객 테이블에 잠김을 걸면 완벽하게 동시성 제어를 할 수 있다. 또 다른 상위 엔터티인 부가서비스는 여러 사용자가 동시에 접근할 가능성이 있어
여기에 잠김을 설정하면 동시성이 나빠질수 있지만, 고객 테이블은 그럴 가능성이 희박하기 때문에 동시성에 미치는 영향은 거의 0에 가깝다.