다음 이전 차례

5. Large Object with Transaction

5.1 Large Object와 예제

포스트그레스에서는 한 튜플의 사이즈가 8192 Byte (8k Bytes) 로 제한되어 있다. 하나의 레코드에 들어갈 수 있는 데이타의 총 크기가 제한되어 있으므로 이미지나 사이즈가 8K 를 넘는 문서들은 다르게 저장되어야 한다.

포스트그레스는 Large Object 라는 개념으로 이를 극복하려한다. 과거에 포스트그 레스는 이런 큰 사이즈의 데이타를 위해 3가지의 지원이 있었으나 사용자들사이의 잦은 혼란으로 하나만을 지원하게 되었고 그것은 단순히 데이타베이스안의 데이타로 서의 Large Object 를 지원한다. 이것은 액세스를 할때 느릴수 있지만 엄격한 데이타 무결성을 제공한다.

포스트그레스는 Large Object 를 쪼개어 이를 데이타베이스의 튜플들에 저장한다. B-tree 인덱스는 랜덤한 resd-write 액세스에 대한 빠른 검색을 보증한다.


다음은 예제이다.

--------------------------------------------------------------------
   drop  table  image;

   BEGIN  WORK;

   SET  TRANSACTION  ISOLATION  LEVEL  SERIALIZABLE;

   create table image(
     name    text,
     raster  oid
   );

   insert  into    image (name , raster) 
        values ('snapshot' , lo_import('/usr/local/src/snapshot01.gif') );

   select  lo_export (image.raster , '/tmp/snap.gif') 
        from  image  where name='snapshot';

   COMMIT  WORK;
-----------------------------------------------------------------------
Large Object Note

위의 예제에서 명시적으로 트랜잭션내에서 Large Object 의 처리가 이루어지고 있다. 이는 포스트그레스 6.5 버젼대에서부터의 Large Object 처리에 대한 요구사항으로서 6.5 이전 버젼의 암시적인 트랜잭션 요구사항과는 달리 명시적인 트랜잭션을 요구한 다. 이 요구사항이 무시된다면, 즉 명시적인 트랜잭션문이 작성되지 않는다면 비정 성적인 결과를 만든다.

설명

  BEGIN  WORK;
    사용자 정의 트랜잭션 시작 

  SET  TRANSACTION  ISOLATION  LEVEL  SERIALIZABLE;
    트랜잭션 레벨 중 가장 강력한 SERIZABLE 레벨로 재 설정을 함. 

포스트그레스의 트랜잭션의 디폴트 레벨은 "READ COMMITTED" 로서 트랜잭션 내의 
query 는 이 query 가 실행되기전에 commit 된 데이타만 다룰 수 있다.

SERIALIZABLE 는 포스트그레스의 가장 강력한 트랜잭션 레벨로서 트랜잭션내의 
query는 query시작전이 아닌 그 트랜잭션이 시작되기전에 commit된 데이타만을 
다룰수 있다.

OID 는 객체에대한 포스트그레스의 시스템 관련 식별자이다. 

lo_import(읽어올 데이타의 PATH); 는 데이타를 읽어들이는 Large Object 관련 
내장 함수이다.

lo_export( OID , 데이타가 쓰여질 시스템의 PATH); 는 데이타를 읽어서 꺼내는 
Large Object 관련 내장함수이다.

COMMIT WORK; 는 트랜잭션의 완료를 의미한다. 이로 인해 실질적인 갱신이나 삭제등이 
이루어진다.

5.2 TRANSACTION

트랜잭션의 성격(ACID)

원자성       : 하나의 트랜잭션은 다수의 query를 실행하지만 이는 단지 하나의
(ATOMIC)       query 인양 실행되어야 한다.  

일관성       : 트랜잭션의 수행에 대해 데이타베이스의 데이타들의 일관성은 
(CONSISTENT)   유지되어야 한다. 

분리         : 각 트랜잭션은 분리되어 다른 트랜잭션중에 간섭해서는 안된다.
(ISOLATABLE)   이는 병렬 (CONCURRENCY) 제어의 개념으로 데이타베이스는 멀티
               유저 환경일 수 있으므로 각 유저의 트랜잭션은 안전하게 이루
               어져야 한다. 

영구성       : 트랜잭션의 수행후 commit 된 데이타들은 영구적으로 유지되어야 
(DURABLE)      한다.

트랜잭션 관련 SQL 명령어 정리

BEGIN [WORK | TRANSACTION]

   BEGIN : 새로운 트랜잭션이 Chain Mode로 시작했음을 알린다.
   WORK , TRANCTION : Optional Keyword. They have no effect.
COMMIT [WORK | TRANSACTION]

   트랜잭션후 변경된 결과를 저장.
END [WORK | TRANCTION]

   현재 트랜잭션을 COMMIT.
   END는 포스트그레스 확장으로서 COMMIT 와 같은 의미이다.
LOCK [TABLE] name

LOCK [TABLE] name IN [ROW | ACCESS] {SHARE | EXCLUSIVE} MODE

LOCK [TABLE] name IN SHARE ROW EXCLUSIVE MODE

  명시적으로 트랜잭션 내의 테이블을 잠금.
ROLLBACK [WORK | TRANSACTION]

   현재 트랜잭션을 중지한다.
 
ABORT [WORK | TRANSACTION]

   현재 트랜잭션을 중지한다. ABORT 는 포스트그레스 확장으로 ROLLBACK와
   같은 의미로서 쓰인다.
 
SET TRANSACTION ISOLATION LEVEL {READ COMMITTED | SERIALIZABLE}

   현재 트랜잭션에 대한 분리 레벨을 설정한다.
   
설명

   INSERT INTO tab VALUES('qwe','www',123);
   
위의 INSERT문 이 성공적으로 수행되었다면 commit 될것이다.
아니면 RollBack 될것이다. 다시 말해,  위의 문이 성공하면 
데이타베이스에 그에  따른  데이타가 저장되고 그렇지 않고 
INSERT 의 실행결과가 ERROR 이면 데이타는 저장되지 않는다.
   
이를 autocommit 라 하는데 또한 다른말로 unchained mode
라고도 한다. 

포스트그레스에서의 일반적인 명령들의 실행은 unchained mode 이다.
그리고 이를 좀 더 그술적으로 서술하면 다음과 같다.
   
"각각의 문장(statement)들은 암시적인 트랜잭션내에서 실행되어지고 
그 문장의 끝부분에서 commit가 이루어지는데 실행이 성공적이면 commit
가 행해지고 반대로 실행이 성공적이지 않으면 rollback 되어진다."
   
결국은 개별적인 SQL 문들의 실행에 있어 사용자들은 자신도 모르게 
트랜잭션내에서 수행하고 있고 또한 그 결과도 자신도 모르게 commit
이거나 rollback이 이루어진다.


BEGIN 은 명시적으로 트랜잭션을 시작함을 의미하며 autocommit 이 되지
않는다(chained mode). 명시적인 commit 문이 올때까지 작업들의 결과들이
데이타베이스에 저장되지 않는다.

BEGIN 문 바로 뒤에 SET 문을 사용하여 그 트랜잭션의 트랜잭션 분리 레벨
을 지정할 수 있다. SET 문의 예는 다음과 같다.


   BEGIN WORK;
     SET  TRANSACTION  ISOLATION  LEVEL  SERIALIZABLE 
     INSERT INTO tab VALUES(1,2,3);
     INSERT INTO tab VALUES(3,4,5);
   COMMIT WORK;

트랜잭션 분리 정책은 여러 유저의 동시성 에 대한 보다 강력한 제한이라 할 
수 있겠다. 포스트그레스에의 디폴트 트랜잭션 분리레벨은 "READ COMMITTED"
이다. READ COMMITTED 보다 더욱더 엄격한 레벨이 SERIALIZABLE 이다.

다음 이전 차례