메뉴 건너뛰기

bysql.net

3._비관적_vs._낙관적_동시성_제어

2012.03.26 08:53

dasini 조회 수:6176

  
 . 비관적 동시성 제어 
           - 사용자 들이 같은 데이터를 동시에 수정 할 것이라 가정
           - 한 사용자가 데이터를 읽는 시점에 Lock를 걸고 조회 또는 갱신 처리가 완료 될때까지 이를 유지

 

 . 낙관적 동시성 제어
          - 사용자들이 같은 데이터를 동시에 수정하지 않은 것이라 가정
          - 데이터를 읽을 때에는 Lock을 설정하지 않음
          - Lock을 유지하는 시간이 매우 짧아져 동시성을 높이는데 유리
              But, 다른 사용자가 같은 데이터를 변경했는지 검사하고 그에 따라 분기해나가는 튜닝 절차가 필요


(1) 비관적 동시성 제어

                                                                                       

SELECT 적립포인트 , 방문횟수, 최근방문일시, 구매실적 FROM 고객
WHERE 고객번호 = : CUST_NUM FOR UPDATE;

-- 새로운 적립포인트 계산
UPDATE 고객 SET 적립포인트 = : 적림포인트 WHERE 고객번호 = : CUST_NUM

                                                                                       

 

  - SELECT 문에 FOR UPDATE를 사용하여 해당 고객 레코드에 LOCK을 걸어둔다면
    데이터가 잘못 갱신되는 문제를 방지할수 있음
    But,  시스템 동시성을 심각하게 떨어뜨릴 우려

 

 

                                                                                       

 for update nowait --> 대기 없이 Exception (ORA-00054)을 던짐
 for update wait 3 --> 3초 대기 후 Exception (ORA-30006)을 던짐

                                                                                       

 

  - wait또는 nowait 옵션을 사용하면, 다른 트랜잭션에 의해 Lock이 걸렸을 때
    Exception을 만나게 되므로 "다른 사용자에 의해 변경 중이므로 다시 시도하십시오"
    동시성을 증가시키게 됨

 

(2) 낙관적 동시성 제어

 

                                                                                       

----- 고객번호를 제외하고 4개 컬럼을 참조

select 적립포인트, 방문횟수, 최근방문일시, 구매실적 into :a, :b, :c, :d
from 고객
where 고객번호 = : cust_num;

 

-- 새로운 적립포인트 계산

update 고객 set 적립포인트 =: 적립포인트
where 고객번호 := cust_num
and 적립포인트 = : a
and 박문횟스 = : b
and 최근방문일시 =: c
and 구매실적 =: d

 

if sql%rowcount = 0 then
 alter ('다른 사용자에 의해 변경되었습니다.');
and if;

 

 

----- 대상 테이블에 최종 변경일시 관리하는 칼럼   mod_dt : 최종변경일시 관리 칼럼
select 적립포인트, 방문횟수, 최근방문일시, 구매실적
into :a, :b, :c, :d, :mod_dt
from 고객
where 고객번호 = : cust_num;

-- 새로운 적립포인트 계산

update 고객 set 적립포인트 =: 적립포인트
where 고객번호 := cust_num
and 변경일시 = :mod_dt;

if sql%rowcount = 0 then
 alter ('다른 사용자에 의해 변경되었습니다.');
and if;

 

----- update 전에 select를 한번 더 수행

select 고객번호
from 고객
where 고객번호 =: cust_num
and 변경일시 = : mod_dt
for update nowait;

 

----- 오라클 10g 부터 사용하는 ora_rowscn을 활용

create table t
ROWDEPENDENCIES
nologging
as
select * from scott.emp;

 

select 적립포인트, 방문횟수, 최근방문일시, 구매실적, ora_rowscn
  into :a, :b, :c, :d, :rowscn
  from 고객
 where 고객번호 = :cust_num;

 

-- 새로운 적립포인트 계산

update 고객
   set 적립포인트 = :적립포인트,
       변경일시 = SYSDATE
 where 고객번호 = :cust_num
   and ora_rowscn = :rowscn ;

 

if sql%rowcount = 0 then
  alert('다른 사용자에 의해 변경되었습니다.');
end if; 

                                                                                       

 

  . ora_rowscn과 scn_to_timestamp 함수를 이용하면 특정 레코드의 갱신시점을 알수 있음

   but , 매핑 테이블의 보관주기는 5일

 

 

번호 제목 글쓴이 날짜 조회 수
26 3._SQL트레이스 sapius 2012.04.04 26838
25 8._Statspack_AWR 시와처 2012.04.01 11469
24 7._Response_Time_Analysis_방법론과_OWI file 시와처 2012.04.01 5733
23 6._V$SYSTEM_EVENT 시와처 2012.04.01 3298
22 4._동시성_구현_사례 [1] dasini 2012.03.27 11683
21 5._오라클_Lock file 시와처 2012.03.26 12566
» 3._비관적_vs._낙관적_동시성_제어 dasini 2012.03.26 6176
19 2._AutoTrace 남송휘 2012.03.26 2914
18 1._Explain_Plan 남송휘 2012.03.26 4322
17 3장._오라클_성능_관리 남송휘 2012.03.26 2888
16 2._트랜잭션_수준_읽기_일관성 file AskZZang 2012.03.20 6136
15 1._트랜잭션_동시성_제어 AskZZang 2012.03.20 4658
14 11._Shared_Pool 박영창 2012.03.19 3155
13 10._대기_이벤트 박영창 2012.03.19 10364
12 9._Snapshot_too_old 박영창 2012.03.19 9726
11 8._블록_클린아웃 시와처 2012.03.19 11991
10 7._Consistent_vs._Current_모드_읽기 file 시와처 2012.03.18 5486
9 2장._트랜잭션과_Lock AskZZang 2012.03.17 5239
8 6._문장수준_읽기_일관성 file 정찬호 2012.03.12 57261
7 4._Redo file 남송휘 2012.03.12 5367