교착상태란
- 두 개 이상의 트랜잭션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를 사용하는 것이 옳다.
더보기
ref. java.ihoney.pe.kr/76
'CS > DataBase' 카테고리의 다른 글
모델링 IE 표기법 _ 객체 다중성 표기법 (0) | 2021.07.13 |
---|---|
인덱스 (0) | 2021.05.02 |
트랜젝션 (0) | 2021.04.29 |
정규화와 반정규화 (0) | 2021.04.28 |
데이터 베이스의 사용 이유와 성능 (0) | 2021.04.28 |
댓글