Open Source RDBMS - Seamless, Scalable, Stable and Free

한국어 | Login |Register

Versions available for this page: CUBRID 8.2.1 |  CUBRID 8.3.0 |  CUBRID 8.3.1 |  CUBRID 8.4.0 |  CUBRID 8.4.1 |  CUBRID 8.4.3 |  CUBRID 9.0.0 | 

잠금 모드의 종류와 호환성

CUBRID는 트랜잭션이 수행하고자 하는 연산의 종류에 따라 획득하고자 하는 잠금 모드를 결정하며, 다른 트랜잭션에 의해 이미 선점된 잠금 모드의 종류에 따라 잠금 공유 여부를 결정한다. 이와 같은 잠금에 대한 결정은 시스템이 자동으로 수행하며, 사용자에 의한 수동 지정은 허용되지 않는다. CUBRID의 잠금 정보를 확인하기 위해서는 cubrid lockdb db_name 명령어를 사용하며, 자세한 내용은 잠금(lock) 상태 확인을 참고한다.

  • 공유 잠금(shared lock, S_LOCK) : 객체에 대해 읽기 연산을 수행하기 전에 획득하며, 여러 트랜잭션이 동일 객체에 대해 획득할 수 있는 잠금이다.
  • 트랜잭션 T1이 특정 객체 X에 대해 읽기 연산을 수행하기 전에 공유 잠금을 먼저 획득하고, 트랜잭션 T1이 커밋되기 전이라도 읽기 연산을 완료하면 즉시 획득한 공유 잠금을 해제한다. 이때, 트랜잭션 T2, T3은 동시에 X에 대해 읽기 연산은 수행할 수 있으나 갱신 연산은 수행할 수 없다.
  • 배타 잠금(exclusive lock, X_LOCK) : 객체에 대해 갱신 연산을 수행하기 전에 획득하며, 하나의 트랜잭션만 획득할 수 있는 잠금이다.
  • 트랜잭션 T1이 특정 객체 X에 대해 갱신 연산을 수행하기 전에 배타 잠금을 먼저 획득하고, 갱신 연산을 완료하더라도 트랜잭션 T1이 커밋될 때까지 배타 잠금을 해제하지 않는다. 따라서, 트랜잭션 T2, T3은 트랜잭션 T1이 배타 잠금을 해제하기 전까지는 X에 대한 읽기 연산도 수행할 수 없다.
  • 갱신 잠금(update lock, U_LOCK) : 갱신 연산을 수행하기 전, 조건절에서 읽기 연산을 수행할 때 획득하는 잠금이다.
  • 예를 들어 WHERE 절과 결합된 UPDATE 문을 수행하는 경우, WHERE 절에서 인덱스 검색을 하거나 풀 스캔 검색을 수행할 때 행 단위로 갱신 잠금을 획득하고, 조건을 만족하는 결과 행들에 대해서만 배타 잠금을 획득하여 갱신 연산을 수행한다. 이처럼 갱신 잠금은 실제 갱신 연산을 수행할 때 배타 잠금으로 변환되며, 이는 다른 트랜잭션이 동일한 객체에 대해 읽기 연산을 수행하지 못하도록 하므로 준 배타 잠금이라고 할 수 있다.
  • 의도 잠금(내재된 잠금, intention lock) : 특정 단위의 객체 X에 걸리는 잠금을 보호하기 위하여 X보다 상위 단위의 객체에 내재적으로 설정하는 잠금을 의미한다.
  • 예를 들어, 특정 행에 공유 잠금이 요청되면 이보다 계층적으로 상위에 있는 테이블에도 의도 공유 잠금을 함께 설정하여 다른 트랜잭션에 의해 테이블이 잠금되는 것을 예방한다. 따라서, 의도 잠금은 계층적으로 가장 낮은 단위인 행에 대해서는 설정되지 않으며, 이보다 높은 단위의 객체에 대해서만 설정된다. 의도 잠금의 종류는 다음과 같다.
    • 의도 공유 잠금(intention shared lock, IS_LOCK) : 특정 행에 공유 잠금이 설정됨에 따라 상위 객체인 테이블에 의도 공유 잠금이 설정되면, 다른 트랜잭션은 칼럼을 추가하거나 테이블 이름을 변경하는 등의 테이블 스키마를 변경할 수 없고, 모든 행을 갱신하는 작업을 수행할 수 없다. 그러나 일부 행을 갱신하는 작업이나, 모든 행을 조회하는 작업은 허용된다.
    • 의도 배타 잠금(intention exclusive lock, IX_LOCK) : 특정 행에 배타 잠금이 설정됨에 따라 상위 객체인 테이블에 의도 배타 잠금이 설정되면, 다른 트랜잭션은 테이블 스키마를 변경할 수 없고, 모든 행을 갱신하는 작업은 물론, 모든 행을 조회하는 작업은 수행할 수 없다. 그러나, 일부 행을 갱신하는 작업은 허용된다.
    • 공유 의도 배타 잠금(shared with intent exclusive, SIX_LOCK) : 계층적으로 더 낮은 모든 객체에 설정된 공유 잠금을 보호하고, 계층적으로 더 낮은 일부 객체에 대한 의도 배타 잠금을 보호하기 위하여 상위 객체에 내재적으로 설정되는 잠금이다.
    • 테이블에 공유 의도 배타 잠금이 설정되면, 다른 트랜잭션은 테이블 스키마를 변경할 수 없고, 모든 행/일부 행을 갱신할 수 없으며, 모든 행을 조회할 수 없다. 그러나, 일부 행을 조회하는 작업은 허용된다.

위에서 설명한 잠금들의 호환 관계(lock compatibility)를 정리하면 아래의 표와 같다. 호환된다는 것은 잠금 보유자(lock holder)가 객체 X에 대해 획득한 잠금과 중복하여 잠금 요청자(lock requester)가 잠금을 획득할 수 있다는 의미다. 한편, N/A는 해당 사항이 없음을 의미한다.

잠금 호환성

 

잠금 보유자(lock holder)

NULL_LOCK

IS_LOCK

S_LOCK

IX_LOCK

SIX_LOCK

U_LOCK

X_LOCK

잠금 요청자
(lock requester)

NULL_LOCK

TRUE

TRUE

TRUE

TRUE

TRUE

TRUE

TRUE

IS_LOCK

TRUE

TRUE

TRUE

TRUE

TRUE

N/A

FALSE

S_LOCK

TRUE

TRUE

TRUE

FALSE

FALSE

FALSE

FALSE

IX_LOCK

TRUE

TRUE

FALSE

TRUE

FALSE

N/A

FALSE

SIX_LOCK

TRUE

TRUE

FALSE

FALSE

FALSE

N/A

FALSE

U_LOCK

TRUE

N/A

TRUE

N/A

N/A

FALSE

FALSE

X_LOCK

TRUE

FALSE

FALSE

FALSE

FALSE

FALSE

FALSE

  • NULL_LOCK : 아무 잠금도 없는 상태
예제

session 1

session 2

;autocommit off

AUTOCOMMIT IS OFF

set transaction isolation level 4;

Isolation level set to:

REPEATABLE READ SCHEMA, READ COMMITTED INSTANCES.

;autocommit off

AUTOCOMMIT IS OFF

set transaction isolation level 4;

Isolation level set to:

REPEATABLE READ SCHEMA, READ COMMITTED INSTANCES.

 

/*

C:CUBRID>cubrid lockdb demodb

 

*** Lock Table Dump ***

 

Object Lock Table:

        Current number of objects which are locked    = 0

        Maximum number of objects which can be locked = 10000

*/

SELECT nation_code, gold FROM participant WHERE nation_code='USA';

 nation_code                  gold

======================================

'USA'                          36

'USA'                          37

'USA'                          44

'USA'                          37

'USA'                          36

 

/*

C:CUBRID>cubrid lockdb demodb

*** Lock Table Dump ***

 

Object type: Root class.

LOCK HOLDERS:

    Tran_index =   2, Granted_mode =  IS_LOCK, Count =   1, Nsubgranules =  1

 

Object type: Class = participant.

LOCK HOLDERS:

    Tran_index =   2, Granted_mode =  IS_LOCK, Count =   2, Nsubgranules =  0

*/

 

 

UPDATE participant SET gold = 11 WHERE nation_code = 'USA' ;

SELECT nation_code, gold FROM participant WHERE nation_code='USA';

 

/* no results until transaction 2 releases a lock

 

C:CUBRID>cubrid lockdb demodb

*** Lock Table Dump ***

 

Object type: Instance of class ( 0|   551|   7) = participant.

LOCK HOLDERS:

    Tran_index =   3, Granted_mode =   X_LOCK, Count =   2

 

 

Object type: Root class.

LOCK HOLDERS:

    Tran_index =   3, Granted_mode =  IX_LOCK, Count =   1, Nsubgranules =  3

NON_2PL_RELEASED:

    Tran_index =   2, Non_2_phase_lock =  IS_LOCK

 

 

Object type: Class = participant.

LOCK HOLDERS:

    Tran_index =   3, Granted_mode =  IX_LOCK, Count =   3, Nsubgranules =  5

    Tran_index =   2, Granted_mode =  IS_LOCK, Count =   2, Nsubgranules =  0

*/

 

 

COMMIT;

 

Current transaction has been committed.

nation_code                  gold

=================================

'USA'                          11           

'USA'                          11           

'USA'                          11           

'USA'                          11           

'USA'                          11           

 

/*

C:CUBRID>cubrid lockdb demodb

 

Object type: Root class.

LOCK HOLDERS:

    Tran_index =   2, Granted_mode =  IS_LOCK, Count =   1, Nsubgranules =  1

 

Object type: Class = participant.

LOCK HOLDERS:

    Tran_index =   2, Granted_mode =  IS_LOCK, Count =   3, Nsubgranules =  0

*/

 

COMMIT;

 

Current transaction has been committed.

 

/*

C:CUBRID>cubrid lockdb demodb

 

Object Lock Table:

        Current number of objects which are locked    = 0

        Maximum number of objects which can be locked = 10000

*/