2016-09-16 3 views
0

각 행에 대한 테이블 트랜잭션에서 number_order를 생성해야합니다 (순서는 1, 2, 3 ...입니다). 내 솔루션 테이블 트랜잭션에 대한 삽입 전에 트리거를 만듭니다. 트리거의 임무는 테이블의 총 행 수입니다 (트랜잭션에서 v_count로 셀 수 선택 (1)) -> 다음 설정 : new.num_order = v_count + 1트리거에서 멀티 스레딩을 처리하십시오.

거의 모든 경우에 해당 솔루션을 실행할 수 있지만 시스템이 많은 경우 많은 쓰레드가 테이블에 삽입되고, 멀티 쓰레딩에 의해 실행되는 트리거와 같은 명령을 반환합니다 (이유는 select 명령이 삽입되기 전에 같은 시간에 &이라고 부름). 대체 솔루션을 알려 줄 수 있습니까? 미리 감사드립니다. P/s : Oracle 12c 데이터베이스를 사용하고 있습니다. 그리고 순서는 실제로 테이블의 다른 열 (예 : Room_id)을 기반으로하므로 시퀀스를 사용할 수 없습니다. 따라서 전체 선택 명령은 다음과 같습니다. select count (1) to v_count from room_id = : new.room_id)

답변

1

일반적으로 이는 심각한 성능, 확장 및 지원 문제로 이어질 수있는 잘못된 접근 방법입니다. 나는 디자인을 재고 할 것이다.

이렇게하려면 트랜잭션을 강제로 serialize해야합니다. 기본 키가 room_id이고 값이 room_count 인 별도의 테이블을 만들거나이 열을 room에 추가 할 수 있습니다. select for update을 통해 room_id 행을 잠 가야합니다. 그런 다음 room_count을 업데이트하고 insert에 사용합니다. 트랜잭션이 커밋되면 잠금이 해제됩니다.

그러나 이와 같이 수행하면 동일한 room_id이 포함 된 다른 모든 트랜잭션이 차단됩니다. 상대적으로 짧은 트랜잭션이있는 경우 같은 방에서 너무 많은 사용자가 작업하지 않는다고 가정하면 끔찍하지 않을 수 있습니다. 그러나 사용자 수와 트랜잭션 길이가 늘어남에 따라 문제는 훨씬 어려워집니다. 거래가 여러 회의실을 포함 할 수있는 경우 교착 상태를 피하기 위해 모든 거래가 동일한 순서 (예 : room_id 주문)로 처리해야합니다. 이 테이블 이상으로 비슷한 것을하려고한다면 상황은 더욱 복잡해집니다.

나는 오히려 시퀀스를 사용하여 쿼리에서 순차 값을 생성합니다. 예를

SELECT room_id, 
     rank() over (partition by room_id order by sequence_column) your_num_order 
    FROM your_table 

또는 위해 당신은 초기 삽입에 대한 sequence_column를 사용하고 정기적으로 (매일 공통) 백그라운드 작업을하고 거래 완료 후 배치에 num_order를 할당 할 수있다.

+0

정말 고마워요. 하지만이 솔루션은 나를 위해 복잡해 보입니다. – Khoa

+0

@Khoa 요구 사항에 숨겨진 함정이 복잡하기 때문에 솔루션은 복잡합니다. –

-1

나는 해결책 다음 제안합니다 : 새 테이블

create table room_count(room_id NUMBER primary key, cnt number); 

기능을 자율적 트랜잭션 수를 증가시키는 :

Create or replace function inc_room_cnt(p_room_id NUMBER) return number as 
PRAGMA autonomous_transaction; 
    v_cnt NUMBER; 
begin 
    update room_count set cnt = cnt +1 where room_id = p_room_id returning cnt into v_cnt; 

    -- insert new room if not yet exists 
    if SQL%ROWCOUNT = 0 then 
    v_cnt := 1; 
    insert into room_count values (p_room_id, v_cnt); 
    end if; 

    commit; 
    return v_cnt; 
end; 
/

before insert 트리거는을 설정 inc_room_cnt를 호출 할 수 있습니다 주문 :

:new.room_order := int_room_cnt(:new.room_id); 
+0

고맙습니다. – Khoa

관련 문제