database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 2169 게시물 읽기
No. 2169
Re: 트랜잭션 테스트를 해 봤는데 이상한 일이... 쩝
작성자
정재익
작성일
2001-01-18 15:28
조회수
5,627

일단 말씀해 주신 내용은 상당히 중요한 정보이고, 유용한 정보입니다. 감사드립니다. 그리고 아래 답변을 보니 확실히 conn.begintrans 로 transaction 을 시작하는 것과 BEGIN WORK 로 transaction 을 시작하는 것에는 차이가 나는 것 같습니다.

TRANSACTION 을 실행시 transaction 이 어느 정도로 독립적으로 운영되는 가 하는 것은 DBMS 를 설계한 사람의 policy 에 따라 많이 달라 질수 있다고 생각합니다. 대표적으로 isolation level 을 규정할 수 있는데 이 isolation level 이 transaction 을 실행에 상당한 영향을 미친다고 생각합니다. (자세한 것은 메뉴얼을 참조하시기 바랍니다. 실제로 SQL92 에서는 4종류의 isolation level 을 정의하고 있으며, PostgreSQL 의 경우 이중 두 level 의 isolation level 을 지원합니다.)

 

님의 글을 읽고 개인적으로 생각되는 바는 transaction을 처리하는 방법이 ODBC 에서 하는 것과 PostgreSQL 의 DBMS 에서 처리하는 것이 서로 다른 방법을 사용하는 것이 아닌가 하는 것입니다. 정확히 ODBC 프로그래밍 경험이 없어 확답할 수는 없지만 그 결과에 차이가 난다는 점에서 그럴수도 있겠다는 생각이 듭니다.

 

다른 문제는 아래 님의 글을 읽으면서 생각해 보기로 하겠습니다. 그 글 아래에 개인적인 생각을 달아 보도록 하겠습니다.

 

>>어떤생각 님께서 쓰시길<<

 

:: 먼저 결과부터 말하면

:: ODBC관리자에서 내리는 Lock 명령은 실행되지 않는다. 입니다.

::

:: 즉,

:: conn.open (ODBC관리자에 새로운 연결을 생성)

:: conn.begintrans (트랜잭션 시작)

:: conn.execute "lock table test in share mode" (Lock 명령 실행)

:: conn.execute "insert...." (insert 명령 실행)

:: conn.execute "delete ...." (delete 명령 실행)

:: conn.committrans (트랜잭션 완료)

:: conn.close (ODBC 연결해제)

::

:: 이렇게 실행하면 Lock이 걸리지를 않습니다. 중간에 다른 insert문을 다른

:: 프로세스에서 실행하면 실행이 되는 거지요. 하지만 commit할때 중간에

:: 끼어든 insert명령으로 인하여 생긴 레코드가 원래 transaction시작시에는

:: 없던 것이었기 때문에 commit되는 순간 사라져버립니다. 그래서

:: 데이타베이스 무결성은 유지됩니다. (흠 이러면 안되는데... 쩝)

 

이상하군요. 그렇던가요. 만약 transaction level 이 serializable isolation level 로 설정되어 있는 상태라면 동시에 실행중인 다른 uncommitted transaction 이 존재하는 경우, 후에 실행중인 transaction 에서 update/insert 등의 writing 을 요구하는 작업은 기존의 transaction 이 commit/rollback 하기까지 대기하게 되어 있습니다.

 

::

:: 하여간 이렇게 하면 안되지만 다음처럼하면

::

:: conn.open (ODBC관리자에 새로운 연결을 생성)

:: conn.execute "begin work" (트랜잭션 시작)

:: conn.execute "lock table test in share mode" (Lock 명령 실행)

:: conn.execute "insert...." (insert 명령 실행)

:: conn.execute "delete ...." (delete 명령 실행)

:: conn.execute "commit work" (트랜잭션 완료)

:: conn.close (ODBC 연결해제)

::

:: Lock이 실행됩니다. Lock table문이 실행된 이후에 다른 프로세스에서

:: insert나 delete등의 문을 실행 하면 table이 Lock이 걸려있기 때문에

:: insert문이 실행되지 않고 대기중의 상태로 들어갑니다. lock이

:: 걸리는 것이지요.

::

:: 그런데 이상한것은 이 Lock이 commit이 될때까지 유지되는 것이 아니라

:: lock명령 다음의 insert문이 실행되면 풀려버립니다.

:: 즉, 트랜잭션실행

:: /> lock으로 테이블을 잠군다.

:: /> 다른프로세스에서 insert문을 실행하면 대기 상태로 들어간다.

:: /> lock다음의 insert문을 실행한다.

:: /> 그러면 Lock이 풀리고 대기상태의 다른 insert문이 실행된다.

:: /> lock다음다음줄의 delete문을 실행한다.

:: /> commit을 실행하면 중간에 끼어든 insert문에 의한 새로운 레코드는

:: 없어진다. 의 동작이 발생하게 됩니다.

:: 이상하죠...^^

 

그렇군요. 정말 이상하군요 /./;

위의 로직과의 차이점은 connection 을 열어 준후에 begin work 로 하나의 트랜젝션을 열어 주었다는 것만이 차이점인데 말이죠 /./

 

:: 또 다른 이상한점.

:: 트랜잭션실행

:: /> lock으로 테이블을 잠군다.

:: /> 다른프로세스에서 begin work을 실행

:: /> 다른 프로세스에서 lock으로 테이블을 다시 잠군다.

:: (그러면 원래 lock이 걸려 있으니까 두번째 lock이 걸리지 않고 대기

:: 할줄 알았는데 의외로 두번째 Lock이 걸리네요...흠)

:: /> 원래 프로세스에서 insert문을 실행하면 두번째 Lock때문에 insert가

:: 실행되지 않고 대기 상태로 들어간다. (에구 정말 이상하다)

:: /> 다른 프로세스(두번째 Lock을 건)에서 insert문을 실행한다. 그러면

:: deadlock detected message가 나오고 이 트랜잭션이 실패했다고

:: 나오는군요. 그러면서 두번째 Lock이 풀립니다. (이건 또 원래의 Lock

:: 때문인가 보죠...)

:: /> 그러면 대기상태의 원래 insert문이 실행된다.

:: /> 그리고 다음의 delete문을 실행한다.

:: /> commit을 실행된다.

:: 의 동작이 발생하게 됩니다.

:: 더 이상하죠...^^ 원래 Lock이 걸려 있으면 그 다음 Lock을 걸려고 하면

:: 충돌하여 대기상태로 들어가게 되는 것 아닌가요? 원래 Lock이 풀릴때까지...

 

당연히 그렇게 되어야 할 것 같은데 말이죠. 그런데 문제는 현재 실행한 LOCK 의 레벨이 share mode 로 걸려 있다는 것이죠. 이것을 EXCLUSIVE mode 로 한번 테스트를 해 보면 어떨까요. 아마도 두번째 lock 의 시도가 실패하지 않을까 싶네요.

그런데 이런 장난 치다가는 가끔 deadlock 에 빠지는 경우가 있겠지요. 하지만 PostgreSQL 의 경우 이에 대한 대비는 어느 정도 되어 있는 것 같으니 한번 테스트 해 보세요. :/)

 

::

:: 제가 원래 생각했던 대로라면

:: 원래 프로세스에서 트랜잭션을 시작한다.

:: /> lock을 건다. (그러면 이후에 다른 프로세스에서 오는 모든 lock이나 insert등의 명령이 대기상태

:: 에 들어간다.)

:: /> 명령들을 모두 실행한다.

:: /> commit을 한다. 그러면 lock이 풀린다.

:: /> 이제 대기상태에 있던 다른 프로세스 명령들이 실행된다.

:: 의 동작이 일어나야 하는거 아닌가요?

::

:: 에구 제가 잘못알고 있는점이 있다면 설명을 부탁드립니다. Lock이 혹시 유지 시간을 갖구있나?... 쩝.

 

위의 모든 문제들이 아마도 ODBC 드라이브에서 deadlock 을 처리하는 과정의 차이에서 발생하는 것이 아닌가 싶습니다. 실제로는 ODBC 드라이버에서 begintrans 로 접속을 시켜도 혹시 그냥 단순한 connection open 만 하는 것은 아닐까요? 이 부분은 저가 정확히 모르겠습니다. 한번 확인해 보시기 바랍니다. 이 부분은 저가 좀더 공부를 해야 정확한 답변이 될 것 같습니다. 혹시 추가적인 정보를 얻게 되면 posting 해 주시면 감 사드리겠습니다.

[Top]
No.
제목
작성자
작성일
조회
2158게시판 소스를~~~~~~~~~
veryy
2001-01-16
5889
2166┕>Re: 게시판 소스를~~~~~~~~~
엠브리오
2001-01-18 13:25:27
6358
2155시간 정보를 PostgreSQL 에 저장하고자 한다면...
정재익
2001-01-16
5738
2185┕>Re: 시간 정보를 PostgreSQL 에 저장하고자 한다면... 2
김상기
2001-01-22 04:29:52
9241
2154PostgreSQL 7.0.3 설치가 안되요~
초보
2001-01-16
5093
2156┕>Re: PostgreSQL 7.0.3 설치가 안되요~
정재익
2001-01-16 12:16:34
5567
2157 ┕>한번 봐 주세요 ... 에러 화면 입니다.
초보
2001-01-17 09:29:19
5292
2152odbc의 conn.begintrans와 sql문의 begin work과의 차이는?
어떤생각
2001-01-15
4252
2153┕>Re: odbc의 conn.begintrans와 sql문의 begin work과의 차이는?
정재익
2001-01-16 00:09:05
4820
2164 ┕>트랜잭션 테스트를 해 봤는데 이상한 일이... 쩝
어떤생각
2001-01-16 20:20:49
4830
2169  ┕>Re: 트랜잭션 테스트를 해 봤는데 이상한 일이... 쩝
정재익
2001-01-18 15:28:47
5627
2150데이타 베이스 초기화는 성공했으니 데몬은 실패하는 이유가 몰까요?
나그네
2001-01-13
4403
2151┕>Re: 데이타 베이스 초기화는 성공했으니 데몬은 실패하는 이유가 몰까요?
정재익
2001-01-13 18:32:46
5531
2147어떤 디렉트로의 어떤내용을 백업 받나요
밝은세상
2001-01-12
3685
2149┕>Re: 어떤 디렉트로의 어떤내용을 백업 받나요
정재익
2001-01-13 13:48:42
4262
2145table에 lock 이 걸린것 같은데...
밝은세상
2001-01-12
4240
2146┕>Re: table에 lock 이 걸린것 같은데...
정재익
2001-01-12 13:47:09
4262
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.019초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다