DeadLock이란 둘 이상의 세션이 서로 맞물려 차단된 상태를 말한다. DeadLock이 발생하면 영원히 지속되기 때문에 SQL 서버가 자동으로 찾아내어 해제시켜 준다. DeadLock에는 두가지 종류가 있다.
- -- 세션 1
- BEGIN TRAN
- UPDATE TAB_A SET COL1 = COL1+2 WHERE PK = 10
- WAITFOR DELAY '0:0:5'
- UPDATE TAB_B SET COL1 = COL1+2 WHERE PK = 10
-- 세션 1
BEGIN TRAN
UPDATE TAB_A SET COL1 = COL1+2 WHERE PK = 10
WAITFOR DELAY '0:0:5'
UPDATE TAB_B SET COL1 = COL1+2 WHERE PK = 10
- -- 세션 2 : 세션 1과 연달아서 실행한다.
- BEGIN TRAN
- UPDATE TAB_B SET COL1 = COL1+2 WHERE PK = 10
- WAITFOR DELAY '0:0:5'
- UPDATE TAB_A SET COL1 = COL1+2 WHERE PK = 10
-- 세션 2 : 세션 1과 연달아서 실행한다.
BEGIN TRAN
UPDATE TAB_B SET COL1 = COL1+2 WHERE PK = 10
WAITFOR DELAY '0:0:5'
UPDATE TAB_A SET COL1 = COL1+2 WHERE PK = 10
- -- 이 SQL을 세션 1, 2에서 연달아 실행한다.
- DECLARE @NUM INT
- BEGIN TRAN
- SELECT @NUM = VAL + 1 FROM TAB1
- WITH (REPEATABLEREAD)
- WHERE NUMTYPE = 'TestApp'
- WAITFOR DELAY '0:0:5'
- UPDATE TAB1 SET VAL = @NUM WHERE NUMTYPE = 'TestApp'
-- 이 SQL을 세션 1, 2에서 연달아 실행한다.
DECLARE @NUM INT
BEGIN TRAN
SELECT @NUM = VAL + 1 FROM TAB1
WITH (REPEATABLEREAD)
WHERE NUMTYPE = 'TestApp'
WAITFOR DELAY '0:0:5'
UPDATE TAB1 SET VAL = @NUM WHERE NUMTYPE = 'TestApp'
UPDATE Character SET login_count = login_count + 1 , login_time = GETDATE() WHERE name = @IN_NAME;
UPDATE Character WITH (UPDLOCK) SET login_count = login_count + 1 , login_time = GETDATE() WHERE name = @IN_NAME;
- UPDATE TEST_TAB SET VAL = 1 WHERE PK = 10
UPDATE TEST_TAB SET VAL = 1 WHERE PK = 10
- BEGIN TRAN
- UPDATE TEST_TAB SET VAL = 1 WHERE PK = 10
- COMMIT
BEGIN TRAN
UPDATE TEST_TAB SET VAL = 1 WHERE PK = 10
COMMIT
- -- Select와 Update가 한 SQL 내에 섞여 있어 Conversion Deadlock에 취약한 SQL
- UPDATE TEST_TAB
- SET VAL = 1
- WHERE PK IN (SELECT PK FROM TEST WHERE VAL = 10)
-- Select와 Update가 한 SQL 내에 섞여 있어 Conversion Deadlock에 취약한 SQL
UPDATE TEST_TAB
SET VAL = 1
WHERE PK IN (SELECT PK FROM TEST WHERE VAL = 10)
- UPDATE UPDATE_TAB
- SET UPDATE_TAB.MANAGE = 1
- FROM UPDATE_TAB, UPDATE_TAB A
- WHERE A.SEQ = UPDATE_TAB.SEQ AND A.MANAGE = 1
UPDATE UPDATE_TAB
SET UPDATE_TAB.MANAGE = 1
FROM UPDATE_TAB, UPDATE_TAB A
WHERE A.SEQ = UPDATE_TAB.SEQ AND A.MANAGE = 1
교착상태를 방지하기 위해 가급적이면 한 SQL 내에 UPDATE문장과 SELECT 문장을 섞어 쓰는 것을 피해야 한다.
'연구개발 > SQL2005' 카테고리의 다른 글
[SQL 2005 GUIDE] 큰 값 데이터 형식 (0) | 2009.07.06 |
---|---|
트랜잭션 로그 백업(Transaction Log Backup)에 관하여 (0) | 2009.06.28 |
잠금에 관한 고찰(2) - 격리 수준(Transaction Isolation Level)에 대하여 (0) | 2009.06.28 |
잠금에 관한 고찰(1) - 잠금(Lock) 매커니즘에 대하여 (0) | 2009.06.28 |
tempdb 데이터베이스에 대한 동시성 강화 (0) | 2009.06.28 |