커밋되지 않은 동일한 트랜잭션에 삽입 된 데이터를 선택할 수 있습니까?


21

어쩌면 이것은 멍청한 초보자 질문 일지 모르지만 어디서나 답을 찾을 수는 없습니다. 어디에서나 Transaction Isolation동시 트랜잭션 내에서 데이터의 가시성을 해결하는 것에 대해 읽었습니다 . 내 관심사는 단일 트랜잭션 내에서의 행동입니다.

트랜잭션을 시작하고 일부 데이터를 삽입하면 동일하지만 아직 커밋되지 않은 트랜잭션 내에서 바로 선택할 수 있습니까? 그렇다면이 동작을 동시 트랜잭션의 경우 언급 된 트랜잭션 격리와 유사한 방식으로 변경할 수 있습니까?

구체적으로 PostgreSQL 9.4를 대상으로합니다.

답변:


17

예.
동일한 트랜잭션 내에서 수행 한 모든 작업은 동일한 트랜잭션 내의 이후 명령에서 볼 수 있습니다. 커밋되기 전까지는 다른 거래를하지 마십시오. 이것은 "더러운 읽기"가 가능한 경우를 제외하고 모든 격리 수준에 적용됩니다 (Read uncommitted, 질문 자체에는 영향을 미치지 않음).

모든 테이블 행 의 보존 기간TransactionId 과 가시성을 기반으로 MVCC 모델 (Multiversion Concurrency Control)로 구현됩니다 . 동일한 트랜잭션으로 작성된 모든 새 행 버전은 동일 xmin하며 "동시에"발생한 것으로 간주됩니다.

동일한 명령 에 여러 CTE (공통 테이블 표현식) 에 대한 코너 케이스가 있습니다 . 하나는 CTE가 순차적으로 실행된다고 생각할 수 있지만 한 CTE가 다른 CTE를 참조하지 않는 한 순서는 임의적입니다. 그리고 모두 쿼리 시작과 동일한 스냅 샷을 볼 수 있습니다.

예:

고급 예 :


3

해보자 :

CREATE OR REPLACE FUNCTION public.sp_get_user()
 RETURNS json
 LANGUAGE plpgsql
AS $function$BEGIN

INSERT INTO users (name, password) VALUES ('deadeye', 'test');
RETURN row_to_json(row) FROM (SELECT name, password FROM users WHERE name = 'deadeye') row;

END;$function$

이제 테스트 해보자.

SELECT sp_get_user();
{"name":"deadeye","password":"test"}

작동합니다! 어윈 (Erwin)이 말했듯이, 거래에서 만들어진 모든 것은 거래 내부에서 볼 수 있습니다. 격리는 다른 스레드 사이에만 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.