블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


Java AP에서 Locking처리 방법은 Synchronized 를 사용하는 방법이 대표적인데
이 경우에는 하나의 JVM Instance 내에서만 동기화 처리가 가능하다.

시스템을 설계할때, 다중 인스턴스 구조의 부하 분산 환경을 고려한다면, 인스턴스내의 Locking 처리인지 아니면 인스턴스간의 Locking처리가 필요한지를 먼저 결정해야 하고, 인스턴스간의 Locking처리인 경우에는 DB나 아니면 기타 (RMI,JMS등) 방법을 사용하는 방식이 있다.

특히 DB의 Lock 처리 메커니즘을 생각할때 고려할 부분은
보통 다음과 같은 구조로 만드는 경우가 많다.
1: select LOCK
2: if( unlocked){
3: update set LOCK
4: }else { return "Lock이 걸려있음"}
5: 임계구역

그러나 이경우, 두개의 인스턴스 A,B가 있다고 했을때
A가 1을 수행하고 Lock이 없어서 Lock을 잡으려고 시도해서 2라인에 진입했다.
이때 B가 Lock체크를 하기 위해 1에 진입하였다면?
A가 아직 Lock을 잡기 전이기 때문에, 결과적으로 A,B 두개 모두 임계구역에 진입하게 된다. Single Instance인 경우에는 당연히 Synchronized처리로 해결하면 되겠지만,
Multi Instance 인경우 다음과 같은 방안이 있다.

1) select하기 전에 해당 row에 DBLock을 거는 방법
2) select하지 않고 update의 return값으로 체크하는 방법

1) 방안은 DB마다 다르기 때문에 별도로 설명하지 않고
2)의 방안을 보면
1: ret = stmt.exeucteUpdate("UPDATE LOCK");
2: if(ret == 0){ return "Lock이 걸려있음"}
3: 임계구역

stmt.executeUpdate는 update에서 반영된 레코드수를 리턴하기 때문에 이미 lock에 대한 update가 된경우에는 0을 리턴한다.
※ 그러나 JDBC 드라이버에 따라서 executeUpdate에 대해서 update에 대한 리턴값이 무조건 0인경우가 있을 수 있기 때문에 반영전에 테스트를 필요로 한다.
본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요