Select ... For Update(Lock)에 대해서 궁금한 점이 있습니다. 조언바랍니다. 0 1 12,066

by 손님 Lock [2008.12.10 21:52:49]


저장 프로시저 작성중 Select ... For Update(Lock)에 대해서 궁금한 점이 있어서
글을 올립니다.

Oracle 버전을 10g입니다.

저장 프로시저에서 사용하는 테이블은 총 4개입니다.
하지만 저장 프로시저 호출시 전달된 파라미터에 따라서 2개의 테이블만 사용합니다.

즉 4개의 테이블을 A,B/C/D라고 한다면 저장 프로시저 호출시 전달된 파라미터에 따라서
A/B, A/C, A/D 2개의 테이블만 사용합니다.

저장 프로시저의 로직을 설명드리면 호출시 전달된 파라미터를 이용해서
1. A 테이블에서 SELECT문의 WHERE 조건을 만족하는 레코드 개수(COUNT)를 조회한 다음
   COUNT가 얼마를 초과하면 Exception을 발생시키고 저장 프로시저를 종료합니다.

2. 1번을 통과하면 역시 전달된 파라미터를 이용하여 B/C/D 테이블 중에 하나를 선택하여
   특정 레코드(1개)의 컬럼 몇개를 조회한 다음 컬럼의 값을 체크합니다.
   비지니스 로직에 따라 컬럼의 값을 체크한 다음 조건을 만족시키지 못하면
   Exception을 발생시키고 저장 프로시저를 종료합니다.

3. 2번을 통과하면 B/C/D 테이블 중에 하나를 선택하여 특정 컬럼의 값을 조회한 다음
   저장 프로시저에 선언된 변수에 임시로 저장합니다.

4. B/C/D 테이블 중에서 하나를 선택하여 선택된 테이블의 특정 컬럼의 값을
   저장 프로시저 호출시에 전달된 또 다른 파라미터 값만큼
   비지니스 로직에 따라서 +/- 시킵니다.
   즉 Update 작업을 수행합니다.

5. 마지막으로 저장 프로시저 호출시 전달된 파라미터를 이용하여
   A 테이블에 INSERT와 UPDATE 두개의 작업을 수행합니다.


위에서 말한 1부터 5까지의 로직이 하나의 프로세스일때
제가 궁금한 점은

1. 위 로직중 1, 2, 3번의 각 SELECT 쿼리에 For Update를 이용하여 Lock을 설정했을때
   Lock 해제는 어떻게 하는지 궁금합니다.
  
2. 1, 2, 3번의 각 SELECT 쿼리에 설정된 각각의 Lock은 위 4, 5번 작업이 끝난 다음 
   한꺼번에 해제해야 하는게 맞나요? 아니면 각각의 Select 작업이 끝난다음 각각
   Lock을 해제해야 하나요?

위에 설명한 로직중 1, 2, 3번은 각각의 함수를 작성하여 저장 프로시저 내부에서
호출하고 있습니다.
         

by sleeper [2008.12.10 22:55:58]
1. commit이나 rollback이 일어나면 현재 트랜잭션에 일어난 모든 select...for update가 풀립니다.
2. select...for update는 심각하게 동시성을 저해합니다. 만약 1번 함수에서 100개가 count 되었을 경우 for update를 걸게 되면 해당되는 모든 row에 lock이 걸리게 됩니다. 빈번한 트랜잭션이 일어나는 테이블이라면 심각한 대기현상을 유발 할 수 있습니다. 1번부터 5번까지 하나의 트랜잭션이라면 for update로 고정 시킬 필요는 없습니다. 한 트랜잭션이 보는 내용은 트랜잭션이 시작되는 시점으로 고정됩니다. 다른 트랜잭션의 dml 결과는 현 트랜잭션에 반영되지 않으므로 for update 사용을 지양하시는 것이 낫다고 판단됩니다. 혹시나 타 트랜잭션에서 변경하고 있는 데이터를 현 트랜잭션에서 확인 없이 변경시키는 경우를 막고 싶은 것이라면 for update nowait를 사용하신 후 실패한 트랜잭션에 관해서 예외처리를 하시기 바랍니다. 그러나 역시 추천하고 싶은 방법은 트랜잭션 설계를 잘 하셔서 for update를 없애는 것입니다.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입