CS/DataBase

교착상태

whyWhale 2021. 5. 1.

교착상태란


  • 두 개 이상의 트랜잭션A가 특정 자원(테이블 또는 행)의 잠금을 획득한 채 다른 트랜잭션A가 소유하고 있는 잠금을 요구하고 또 다른 트랜젝션B가 A가 가지고 있는 잠금을 요구하면 두 트랜잭션이 아무리 기다려도 바뀌지 않는 상태가 되는 경우를 교착상태라고 한다.  

 

데이터베이스 관점 교착상태


 

교착상태

T1이 잠금을 얻고 T2도 잠금을 얻은 경우.

Transaction 1> create table B (i1 int not null primary key) engine = innodb;
Transaction 2> create table A (i1 int not null primary key) engine = innodb;

Transaction 1> start transaction; insert into B values(1);
Transaction 2> start transaction; insert into A values(1);

commit을 하지 않은 채 서로의 잠금을 요구한다.

Transaction 1> insert into A values(1);
Transaction 2> insert into B values(1);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

일반적인 DBMS는 교착상태를 검출해 보고한다.

 

※ 교착상태의 빈도를 낮추는 방법.

  • 트랜잭션을 자주 Commit 한다.
  • 정해진 순서로 테이블에 접근한다
    • T1이 테이블 B->A의 순으로 접근했고 T2 A->B로 접근했다.
    • 트랜잭션이 무조건 A->B 로 갈수있게 통일한다.
    • 읽기 잠금 획득 (select ~ for update)의 사용을 금한다.
    • 한 테이블의 복수 행을 복수의 연결에서 순서 없이 갱신을 하게 되는 경우 교착상태가 자주 발생한다.
      • 이런 경우 테이블 단위의 잠금을 획득해 갱신을 직렬화 하면 동시성은 떨어지지만 교착상태를 회피할 수 있다.

 

+ Statement 와 PreparedStatement

  • 속도 면에서 PreparedStatement가 빠르다.
    • 쿼리를 수행하기 전에 이미 쿼리가 컴파일 되어 있으며, 반복 수행의 경우 프리 컴파일된 쿼리를 통해 수행되기 때문이다.
  • Statemnt에는 보통 변수를 설정하고 바인딩하는 static sql이 사용되고 prepared Statement에서는 쿼리 자체에 조건이 들어가는 dynamic sql이 사용된다. PreparedStatement가 파싱 타임을 줄여주는 것은 분명하지만 dynamic Sql을 사용하는데 따르는 퍼포먼스 저하가 발생한다.
  • 하지만 성능을 고려할 때 테이블에서 레코드를 가져오는 과정에서 시간이 오래걸린다. 
  • SQL문을 파싱하는 시간은 1/10에 불과하다.
  • 그러므로 SQL Injection등의 문제를 보완해주는 PreparedStatement를 사용하는 것이 옳다.

 

 

'CS > DataBase' 카테고리의 다른 글

모델링 IE 표기법 _ 객체 다중성 표기법  (0) 2021.07.13
인덱스  (0) 2021.05.02
트랜젝션  (0) 2021.04.29
정규화와 반정규화  (0) 2021.04.28
데이터 베이스의 사용 이유와 성능  (0) 2021.04.28

댓글