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 7033 게시물 읽기
No. 7033
update table set field=field+1 in transaction
작성자
송효진
작성일
2007-02-03 04:30ⓒ
2007-02-03 04:40ⓜ
조회수
4,538

트랜잭션 내의 field=field+1 이 심히 걱정스럽습니다.

트랜잭션을 안걸었으면 확실하게 1씩 증가하겠지만,

트랜잭션을 걸었으면 트랜잭션이 종료되기 전에

다른 커넥션에서 트랜잭션이 발생할 수 있겠지요.


트랜잭션 A 에서 1 을 증가시켜 2를 만들었는데,

트랜잭션 B 에서는 A 가 커밋되기전에 1을 증가시켰기 때문에 2가 되는 상황이 일어날 것 같습니다.


아직까지는 이런게 정확할 필요가 있는 것이 필요하진 않지만,

조만간 필요해질 듯 하군요.


시퀀스로 어찌 해 보려 했는데, row 수 만큼 만드는것도 아닌것 같아서요.


현재 좋은 방안이 있나요?

이 글에 대한 댓글이 총 4건 있습니다.

DBMS 에서 트랜젝션으 구현하기 힘든 이유가 말씀하신 그런 이유들 때문입니다.

트랜젝션 구현시 가장 먼저 고려해야 할 점이 그런 지금과 같은 그런 상황이죠.

바꾸어 말하면, 말씀하신 상황들에 대한 대처는 충분히 해결되도록 구현되어 있는 것이 트랜젝션의 이점이죠.

즉 사용자는 그런 고려를 할 필요가 전혀 없다는 것입니다.

테스트해 보시면 이해를 할듯...

정재익(neople)님이 2007-02-03 09:24에 작성한 댓글입니다.

메뉴얼 12.2절 transaction isolation 부분이 참고 될 것 같습니다.


위와 같은 경우라면 pgsql의 default transaction isolation level인 read committted에서는 문제가 될 수 있습니다. 먼저 실행된 트랜잭션에서 update한 후에 commit을 안한 상태에서 다른 트랜잭션에서 update를 하면 우려하시는 일이 생기니까요.


dirty read가 필요한 상황 처럼 보이지만 pgsql은 dirty read를 지원하지 않기도 하고 그것이 정답은 아니구요. lock을 생각해야 할 것 같습니다.


두가지 방법이 있을 것 같은데요. 하나는 row level lock을 사용하는 방법과 table lock을 사용하는 방법입니다.


row level lock은 트랜잭션이 끝나기 전에 특정 row에 대해서 lock을 걸어서 update가 안되게 하는 것입니다. UPDATE 명령 전에 UPDATE될 컬럼들에 대해서 SELECT ... FOR UPDATE 구문을 먼저 실행시켜버리는거죠. 이렇게 하면 먼저 실행된 트랜잭션이 commit 되거나 rollback되기 전에는 해당 row들이 lock 상태이기 때문에 다른 트랜잭션에서 실행한 SELECT ... FOR UPDATE 명령이 처리되지 않고 기다리게 됩니다.


table lock은 아시겠지만 table 전체에 lock을 걸어버리는 방법이지요. 확실한 방법이기는 하지만 동시 처리 성능을 심각하게 떨어트리게 됩니다.


update할 row의 수가 전체 table의 일부라면 row lock을 그렇지 않다면 table lock을 쓰는 것이 좋을 것 같네요.

박성철(gyumee)님이 2007-02-03 09:25에 작성한 댓글입니다.
이 댓글은 2007-02-03 11:08에 마지막으로 수정되었습니다.

경험상 그런 상황이면 자동으로 먼저 테이블을 변경한 트랜젝션이 끝날때까지 기다리지 않나요?

신기배(소타)님이 2007-02-03 10:58에 작성한 댓글입니다.

특별히 작업하지 않으면, shared lock 이 걸려, 
우려한 사태가 발생합니다. 

그런 사태라면, 
반드시 

select ... for update 형태로 일단 자료를 가져오고, 
그 다음 update 구문을 사용하든지, 

아니면, 
lock table ... row exclusive 또는 exclusive로 
row 또는 table을 배타적으로 잠궈야합니다.

성철님 말이 맞아요. ^^

김상기(ioseph)님이 2007-02-04 01:56에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
7038비밀번호 입력이 안됩니다;; [1]
초보탈출기
2007-02-06
4614
7036시스템 연동상의 문제 [2]
김일균
2007-02-06
4198
7035조회가 안되는데... [3]
초보
2007-02-06
3995
7033update table set field=field+1 in transaction [4]
송효진
2007-02-03
4538
7032win2k3 에 pgsql 8.2.2 설치 방법[업뎃]
송효진
2007-02-02
3885
7031[쿼리질문](1필드)최소값 중에서 (2필드)최대값을 가진 모든필드 가져오기 [5]
2007-02-01
4172
7030win2k3 에 설치 포기... [3]
송효진
2007-02-01
4553
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다