Isolation의 설정 방법? Syntax for Session-Level Isolation:
set transaction isolation level {
0 | read uncommitted |
1 | read committed |
2 | repeatable read |
3 | serializable }
Syntax for Statement-Level Isolation:
select ...
at isolation {
0 | read uncommitted |
1 | read committed |
2 | read repeatable |
3 | serializable }
a @@isolation returns the isolation level for the session
nonrepeatable 발생 해결하려면?
isolation level을 2,3으로 올려야 한다
예)
현재의 isolation level은 1이고, 여러 page를 차지하는 table을 만든다
1> use sybsystemprocs
2> go
1> create table testTABLE (
2> a char(255),
3> b char(255),
4> c char(255),
5> d char(255))
6> go
1> insert into testTABLE values ('1','1','1','1')
2> insert into testTABLE values ('2','2','2','2')
3> insert into testTABLE values ('3','3','3','3')
4> insert into testTABLE values ('4','4','4','4')
5> insert into testTABLE values ('5','5','5','5')
6> insert into testTABLE values ('6','6','6','6')
7> insert into testTABLE values ('7','7','7','7')
8> insert into testTABLE values ('8','8','8','8')
9> insert into testTABLE values ('9','9','9','9')
10> insert into testTABLE values ('10','10','10','10')
11> insert into testTABLE values ('11','11','11','11')
12> insert into testTABLE values ('12','12','12','12')
13> insert into testTABLE values ('13','13','13','13')
14> insert into testTABLE values ('14','14','14','14')
15> insert into testTABLE values ('15','15','15','15')
16> insert into testTABLE values ('16','16','16','16')
17> insert into testTABLE values ('17','17','17','17')
18> insert into testTABLE values ('18','18','18','18')
19> insert into testTABLE values ('19','19','19','19')
20> insert into testTABLE values ('20','20','20','20')
21> go
1> select @@isolation
2> go
-----------
1 지금부터는 2개의 session A,B를 함께 사용해서 하십시요
*************
session A
*************
1> select @@isolation
2> go
-----------
1
1> -- (1) transaction 을 시작한다
2> begin tran
3> go
1> ---(3) a='1' 인 내용을 select한다. lock은 읽는 순간에만 걸린다
2> select * from testTABLE where a = '1'
3> go
a -- b ---c ---d
--- ---- --- ----
1 ---1 ---1 ---1
1> ---(6) 위에서 select한 내용을 똑같이 시도한다.
-- 그러나, 한 transaction안에서도 값은 위의 select와 똑같지 않다
-- 이것이 바로 nonrepeatable read 이다
2> select * from testTABLE where a = '1'
3> go
a --- b ---c ---d
---- ---- ---- -----
1 -- -1 ---1 ---123
1> ---(7)
2> commit tran
3> go
*************
session B
*************
1> -- (2) transaction 을 시작한다
2> begin tran
3> go
1> -- (4) session A 에서 읽었던 a='1' 인 내용을 update한다.
-- lock은 execluseve로 commit tran을 만날때 까지 풀리지 않는다
2> update testTABLE set d = '123' where a = '1'
3> go
1> ---(5) commit 을 하면, 위의 update로 인한 lock이 풀리고
-- 다른 session에서 update의 변경값을 읽을 수 있다
2> commit tran
3> go
위의 것은 Isolation level 1인 경우입니다. Isolation level 2로 바꾸고 하면 (3)번이 lock을 걸어 (4)번 수행이 되지 않습니다. 그래서 (6)번,(7)번 수행하고 lock이 풀려야 (4)번 수행됩니다
이처럼 Isolation level 2에서는 한 transaction이 1 row를 읽은 것이 transaction이 끝날 때 까지 lock을 걸어 수행이 같은 transaction에서 그 1 row를 다시 읽어도 같은 내용이 읽힙니다
phantom read 발생 해결하려면?
isolation level 3으로 해결할 수 있습니다
예)
현재의 isolation level은 1이고, 여러 page를 차지하는 table을 만든다
1> use sybsystemprocs
2> go
1> create table testTABLE (
2> a char(255),
3> b char(255),
4> c char(255),
5> d char(255)) lock datarows
6> go
1> set transaction isolation level 3
2> go
1> insert into testTABLE values ('1','1','1','1')
2> insert into testTABLE values ('2','2','2','2')
3> insert into testTABLE values ('3','3','3','3')
4> insert into testTABLE values ('4','4','4','4')
5> insert into testTABLE values ('5','5','5','5')
6> insert into testTABLE values ('6','6','6','6')
7> insert into testTABLE values ('7','7','7','7')
8> insert into testTABLE values ('8','8','8','8')
9> insert into testTABLE values ('9','9','9','9')
10> insert into testTABLE values ('10','10','10','10')
11> insert into testTABLE values ('11','11','11','11')
12> insert into testTABLE values ('12','12','12','12')
13> insert into testTABLE values ('13','13','13','13')
14> insert into testTABLE values ('14','14','14','14')
15> insert into testTABLE values ('15','15','15','15')
16> insert into testTABLE values ('16','16','16','16')
17> insert into testTABLE values ('17','17','17','17')
18> insert into testTABLE values ('18','18','18','18')
19> insert into testTABLE values ('19','19','19','19')
20> insert into testTABLE values ('20','20','20','20')
21> go
지금부터는 2개의 session A, B를 함께 사용해서 하십시요
*************
session A
*************
1> -- (1) 현재 isolation level은 2 입니다
1> select @@isolation
2> go
-----------
--- 2
2> begin tran -- transaction 을 시작 합니다
3> go
1> ---(3) 조건 < 9 인 내용을 보았습니다
2> select * from testTABLE where convert(int,a) < 9
3> go
a
-----------------------------------------------------------------------
1
2
3
4
5
6
7
8
1> ---(6) 조건 < 9 인 내용을 보았습니다
-- session B의 영향으로
-- 위의 select결과로 보이지 않던 0가 보인는 phantom현상이 발생했습니다
2> select * from testTABLE where convert(int,a) < 9
3> go
a
-----------------------------------------------------------------------
1
2
3
4
5
6
7
8
0
1> ---(7)
2> commit tran
3> go
*************
session B
*************
1> -- (2) 번호순 대로 수행하세요
2> begin tran
3> go
1> -- (4)
2> insert into testTABLE values ('0','0','0','0')
3> go
1> ---(5)
2> commit tran
3> go
위의 것은 Isolation level 2인 경우이다
Isolation level 2인 경우, 번호순서대로 수행이 가능하나
Isolation level 3로 바꾸고 하시면 (3)번이 lock을 걸어 (4)번 수행이 되지 않는다
그래서 (6)번,(7)번 수행하고 lock이 풀려야 (4)번 수행된다