동시성은 다수의 유저가 동시에 데이터에 접근,수정등을 가능하게 한다.2명의 사용자가 한명은 select를 하고 한명은 update를 하면 다음의 문제가 발생할 것이다.
savepoints는 트랜젝션을 특정시점으로 롤백시킬 수 있는 명령어이다.
BEGIN;
UPDATE product SET price = price+100
WHERE product_name = 'Chair';
SAVEPOINT test_savepoint;
UPDATE product SET price = price+200 // 롤백됨
WHERE product_name = 'Table'; // 롤백됨
ROLLBACK TO test_savepoint;
UPDATE product SET price = price+100
WHERE product_name = 'Table';
COMMIT;
다수의 동시성의 사용자작업이 요구되는 트랜젝션은 격리되어야 한다.같은 데이터에 접근하는 다른유저가 존재할때 이러한 격리를 다루는건 매우 어렵다.리밋을 걸수도 있지만 데이터베이스와 커넥션 한개당 한개의 트랙젝션만 수행된다.이렇게 된다면 다중사용자의 퍼포먼스 저하가 발생할 것이다.
SQL표준은 다중사용자가 트랜젝션을 발생시킬때의 상황을 기반으로 격리수준을 정의한다.이러한 상황을 dirty reads, unrepeatable reads, and phantom reads
라 한다.
트랜젝션이 다른 커밋되지 않은 트랜젝션에 접근가능하면 dirty read
이다.다수의 SQL문으로 작성된 트랜젝션은 원자성(모두 성공하나 모두 실패)을 지켜야 한다.따라서 커밋되지 않거나 아직 롤백되지 않은 작업이 다른 트랜젝션에서 접근가능한 시나리오가 발생할 수 있다.그러므로 데이터베이스 사용자는 커밋전에 변경된 데이터를 확인해야 한다.
위의 표는 dirty reads와 아닌상황을 비교한 표이다.
트랜젝션이 행을 읽은후 다른 선언에 의해 바뀐 같은 행을 읽는 상황이 unrepeatable read
이다.PostgreSQL는 기본적으로 unrepeatable reads를 허용한다.
unrepeatable reads
가 허용되면 다른 트랜젝션은 다른 트랜젝션이 커밋없이 커밋된 데이터에 접근가능하다.반대로 허용되지 않는다면 다른 트랜젝션은 커밋전까지 최신데이터에 접근하지 못한다.
트랜젝션이 조건에 맞는 여러 행을 읽은후 같은조건의 행이지만 변경된 데이터를 읽는다.이는 phantom read
인 다른 트랜젝션으로 인해 가능하다.phantom read
는 dirty read
가 단일값을 지칭했던것과 다르게 데이터 집합이다.기본적으로 postgresql은 phantom read
를 허용한다.
트랜젝션1이 상품의 가격을 100증가시켰다.이 트랜젝션이 커밋되기전에 트렌젝션2가 테이블에 row를 추가시킨다.그러므로 새로운 상품가격이 100만큼 오를것으로 예상한다.하지만 phantom read
에 의해 트랜젝션1이 어떤 row를 업데이트할지 결정한 후 나타난 새로운 record는 트랜젝션1이 커밋되도 업데이트 되지 않는다.
출처
postgresql-development-essentials By Manpreet Kaur , Baji Shaik