-- 준비된 데이터
| EMPNO | SAL | LVL |
| ----- | ---- | --- |
| 1001 | 3000 | 1 |
| 1002 | 3020 | 1 |
| 1003 | 3040 | 1 |
| 1004 | 3030 | 1 |
| 1005 | 3010 | 1 |
| 1006 | 3060 | 1 |
| 1007 | 3070 | 1 |
TX1 TX2
---------------------------------------------------------------------------------------
UPDATE emp SET sal = sal + 1000 t1
WHERE empno = 1004
t2 UPDATE emp SET sal = sal + 200
WHERE empno <= 1007
AND sal <= 4000;
COMMIT; t3
t4 COMMIT;
Case0 ) SqlServer에서 결과는? (SAL ≤ 4,000 조건을 유지하는 경우)
-- 준비된 데이터
| EMPNO | SAL | LVL |
| ----- | ---- | --- |
| 1001 | 3000 | 1 |
| 1002 | 3020 | 1 |
| 1003 | 3040 | 1 |
| 1004 | 3030 | 1 |
| 1005 | 3010 | 1 |
| 1006 | 3060 | 1 |
| 1007 | 3070 | 1 |
TX1 TX2
---------------------------------------------------------------------------------------
UPDATE emp SET sal = sal + 100 t1
WHERE empno = 1004;
-- 1004에 X락을 걸어놓고
-- 업데이트를 진행한다(3030 -> 3130)
-- 그 후 트랜잭션 종료까지 X락을 유지
-- (참고, S락은 순간만 유지)
**t2** SELECT * FROM
UPDATE emp SET sal = sal + 200
WHERE empno <= 1007
AND sal <= 4000;
--current모드 갱신시작
업데이트 -- 1001 ~ 1003 까지 잘 update함
TX2대기 -- 1004에서 TX1 X락이 걸려있어 TX2는 대기
TX2대기
COMMIT; t3 TX2대기 끝
업데이트 --current데이터를 그대로 읽어와서 TX2가 +200 한다.(3130 -> 3330)
업데이트 --1004 ~ 1007 update함
t4 COMMIT;
Case1 ) SqlServer에서 결과는? (SAL ≤ 4,000 조건을 만족하지 않게될 경우)
-- 준비된 데이터
| EMPNO | SAL | LVL |
| ----- | ---- | --- |
| 1001 | 3000 | 1 |
| 1002 | 3020 | 1 |
| 1003 | 3040 | 1 |
| 1004 | 3030 | 1 |
| 1005 | 3010 | 1 |
| 1006 | 3060 | 1 |
| 1007 | 3070 | 1 |
TX1 TX2
---------------------------------------------------------------------------------------
UPDATE emp SET sal = sal + 1000000 t1
WHERE empno = 1004;
-- 1004에 X락을 걸어놓고
-- 업데이트를 진행한다(3030 -> 3130)
-- 그 후 트랜잭션 종료까지 X락을 유지
-- (참고, S락은 순간만 유지)
**t2** UPDATE emp SET sal = sal + 200
WHERE empno <= 1007
AND sal <= 4000;
--current모드 갱신시작
업데이트 -- 1001 ~ 1003 까지 잘 update함
TX2대기 -- 1004 데이터를 TX2 쿼리의 where절에 충족하는 데이터로 보는가? (실습해보자)
Case2 ) 오라클에서의 결과는?
-- 준비된 데이터
| EMPNO | SAL |
| ----- | ---- |
| 1001 | 3000 |
| 1002 | 3020 |
| 1003 | 3040 |
| 1004 | 3030 |
| 1005 | 3010 |
| 1006 | 3060 |
| 1007 | 3070 |
TX1 TX2
---------------------------------------------------------------------------------------
UPDATE emp SET sal = sal + 1000 t1
WHERE empno = 1004;
**t2** --consistent모드 읽기로 식별할 대상 레코드들의 rowId 조회
--TX1에서 +1000증가시킨 사원데이터도 TX2 consistent모드의 시점에서는 여전히 3030 이므로 해당함.
**** UPDATE emp SET sal = sal + 200
WHERE empno <= 1007
AND sal <= 4000;
--current모드 갱신시작
업데이트 -- 1001 ~ 1003 까지 잘 update함
TX2대기 -- 1004에서 TX1 EX모드 row락이 걸려있어 TX2는 대기
TX2대기
COMMIT; t3 TX2대기 끝
업데이트 --TX1이 1004의 레코드의 sal값에 변경을 주었기에 TX2작업을 모두 rollback하고 Restart진행
t4 COMMIT;
- TX2는 t2 시점에 consistent 모드 읽기
- TX2의 consistent모드 읽기는 대기없이 바로 진행된다 (TX1의 commit / rollback 유무를 따지지 않음)
- CR Copy블록에서
empno = 7788 대상 레코드의 rowid를 얻어 식별한다.
- 이후, TX2는 current 모드 갱신
- 1001 ~ 1003 까지 X락이 없으므로 대기없이 바로 update한다.
- 대상 레코드를 TX1이 X락을 걸었기에 락이 풀릴 때까지 TX2는 대기를 한다.
- TX1락이 드디어 풀렸다면 어떤 흐름으로 전개될까?
- case1) TX1에서 where조건에 쓰인 컬럼 이외의 컬럼만 변경했을 때
- 식별대상이 consistent모드로 읽었을 때 대상으로 유지되므로 TX2는 update를 진행한다.
- case2) TX1에서 where조건에 쓰인 컬럼을 변경했을 때
- TX1에 의해 TX2업데이트 중간에 식별대상이 달라졌기 때문에 Restart한다.