2012-02-12 2 views
3

다른 데이터베이스의 삽입 메커니즘에 대한 질문이 있습니다. ID 열과 같이 자동으로 생성되는 단일 열 기본 키가있는 테이블을 사용하면 새 레코드를 삽입 할 때 전체 테이블이 잠길 수 있습니까? 인서트에 시간이 너무 오래 걸리는 경우 다른 트랜잭션이 더 기다려야합니까?데이터베이스 삽입 메커니즘

+1

오라클은 시퀀스를 사용 - IDENTITY이 지금 SQL 서버 2012 지원 [구식 인 SQL Server 관련 용어입니다 ANSI] 시퀀스. –

답변

2

기본적으로 Oracle은 행 레벨 잠금을 사용합니다.

이러한 잠금은 작성자 (업데이트, 삭제, 삽입 등)에만 차단됩니다. 즉 선택 의지가 그 안에이 데이터, 등 예를 들어

, TABLEA (COL1 번호, COL2 수)하자,에서 삭제 테이블이 무거운 업데이트됩니다 모든 시간을 작동 의미

col1 | col2 
1  | 10 
2  | 20 
3  | 30 
time1에서

하면 사용자 John 문제 :

update tableA set col2=11 where col1=1; 

이 ROW1을 잠급니다. time2 사용자 마크 문제 업데이트가 작동 것이다

update tableA set col2=22 where col1=2; 

에서

, 행 2가 잠겨 있지 않기 때문에.

이제 테이블이 데이터베이스에 보이는 : 마크 테이블에 대한

col1 | col2 
1  | 11 --locked by john 
2  | 22 --locked by mark 
3  | 30 

은 들어

col1 | col2 
1  | 10 
2  | 22 
3  | 30 

(그는 미트되지 않은 변경 내용을 볼 수 없습니다) 존 테이블은 다음과 같습니다 (그 변경 사항을 볼 수 없습니다) 미트되지 않은

col1 | col2 
1  | 11 
2  | 20 
3  | 30 

는 표시가 time3에서 시도하는 경우 :

update tableA set col2=12 where col1=1; 
존 (time4에서, DB에)

테이블 인 (롤백도 행 잠금을 해제하지만, 변경 사항이 손실됩니다)를 commit을 발행 할 때 자신의 세션이 time4 때까지 중단됩니다

:.

col1 | col2 
1  | 11 
2  | 22 --locked by mark 
3  | 30 

Immediatley, 요한의 커밋 후 ROW1 잠금이 해제됩니다 마크의 업데이트는 작업을 수행합니다

col1 | col2 
1  | 12 --locked by mark 
2  | 22 --locked by mark 
3  | 30 
을 삽입 된 행이 잠겨 있기 때문에

col1 | col2 
1  | 11 
2  | 20 
3  | 30 

삽입의 경우, 간단하지만 또한 그들이 최선을 다하고되지 않기 때문에 다른 사용자가 보이지 않는 :

는 time5에서의 마크 발행 rollbak을 할 수 있습니다. 사용자가 커밋하면 잠금을 해제하므로 다른 사용자가 이러한 행을 보거나 업데이트하거나 삭제할 수 있습니다.

EDIT : Jeffrey Kemp가 설명했듯이 사용자가 동일한 값을 삽입하려고하면 (고유 인덱스가있는 Oracle에서 구현 됨) PK를 사용하면 인덱스에 이 발생합니다. 두 번째 세션은 동일한 세션에서 쓰기 때문에 첫 번째 세션이 끝날 때까지 차단됩니다. 첫 번째 세션이 커밋되면 두 번째 세션에서 기본 키 위반 예외가 발생하고 데이터베이스를 변경하지 못합니다. 첫 번째 세션이 롤백을 수행하면 두 번째 세션이 성공합니다 (다른 문제가없는 경우).

(NB : 사용자 요한이 설명에서 나는 사용자 John에 의해 시작 세션을 의미한다.)

3

삽입하면 테이블이 잠기지 않습니다. 삽입 된 레코드는 사용자가 커밋하기 전까지는 다른 세션에서 볼 수 없습니다.

+0

커밋에 오랜 시간이 걸리면 전체 테이블이 잠길 것인가? –

+1

아니요, Oracle은 테이블 수준 잠금을 수행하지 않습니다. (사실 엄밀히 말하면, 테이블 레벨 잠금을 수행하는 것이 가능 합니다만, 기본적으로 어떤 일이 일어나지는 않습니다.) Insert는 특별한 경우입니다. 삽입이 일어나는 행에서 잠금이 수행되지만, Oracle이 잠금 및 읽기 일관성을 처리하는 방식으로 인해 삽입 세션이 커밋을 발행 할 때까지 다른 세션은 삽입 된 행을 보지 못합니다. –

+0

그러나 이유에 대한 커밋이 오래 걸리면 전체 테이블이 잠길 것입니다. 나는이 정확한가? (자동 생성 된 기본 키가 있다고 가정) –

2

이 질문은 고유 한 제약 조건이있는 테이블에 삽입하는 경우와 관련이 있습니다. 인덱스가없고 테이블에 행을 삽입하면 데이터베이스가 전체 테이블을 잠글 필요가 있습니다. 그렇지 않으면 다중 사용자 시스템에 중복이 삽입 될 수 있습니다.

그러나 Oracle은 항상 색인을 사용하여 고유 제한 조건을 정책화합니다. 즉, 열에 대한 데이터가 항상 정렬되고 충돌 행이 이미 있는지 여부를 빠르고 쉽게 확인할 수 있습니다. 같은 값을 동시에 삽입하려고 시도하는 여러 세션을 방지하기 위해 오라클은 해당 값에 대한 인덱스의 블록을 잠글 것입니다.이 방법으로 특정 값에 대해서만 전체 테이블에 대한 경합이 발생하지 않습니다. 삽입했다. 그리고 색인 조회가 일반적으로 매우 빠르기 때문에 잠금은 매우 짧은 시간 동안 만 보관하면됩니다.

(하지만 세션에서 값을 삽입했지만 즉시 커밋하지 않는 경우 무엇을 요청할 수 있습니까? 다른 세션에서 동일한 값을 삽입하려고하면 어떻게됩니까? 대답은 두 번째 세션이 대기한다는 것입니다. 같은 인덱스 블록에 대한 잠금을 요청할 것이기 때문에 첫 번째 세션이 아직 커밋되지 않았으므로 블록은 여전히 ​​잠겨 있습니다. 첫 번째 세션이 커밋되거나 롤백되는지 여부를 알 수 없기 때문에 기다려야합니다.)