무작위 방식으로 값 튜플을 연결하고 동시성 제약으로 인해 트랜잭션을 실패 할 가능성이없는 방법을 찾고 있습니다.SQL 병합을 원자 적으로 실행하는 방법이 있습니까?
편집해야하는 표에는 UUID로 설명해야하는 몇 가지 값이 들어 있습니다. 이 예제에서 테이블의 이름은 foo
이며 bar
및 qux
두 개의 문자열 열이 하나의 필드 uuid
을 가리키는 것으로 선언됩니다. (bar, qux)
은 테이블 전체에서 고유해야합니다. UUID는 본질적으로 고유합니다.
는 SQL은 (오라클 12C 사용) 원자 적으로 다음과 같은 일을 할 수 있는지 궁금해 : 내 데이터베이스의 쿼리의 결과로
MERGE INTO foo a
USING (SELECT bar, qux FROM foo b
ON b.bar = 'a' and b.qux = 'b'
WHEN NOT MATCHED THEN INSERT (a.bar, a.qux, a.uuid)
VALUES ('a', 'b', 'some-uuid');
SELECT uuid FROM foo WHERE bar = 'a' and qux = 'b';
을, 나는 (bar, qux)
가 임의의 UUID와 연결되는 튜플을 원하는 . 이 UUID는 모든 동시 트랜잭션에 대해 동일해야하며 다른 (임의의) UUID를 동시에 삽입하므로 경쟁하는 요청이 실패하지 않기를 바랍니다.
배경으로 :이 삽입은 대부분 서로 독립적이지 않지만 값이 일치하지 않아야하는이 공유 된 식별자 테이블을 가지고있는 오랜 기간 실행되는 트랜잭션의 일부입니다. 많은 프로그래밍 언어가 CAS를 제공하며,이 경우에 내가하려는 것이지만 SQL의 smilar 기능을 알지 못합니다. 더러운 허용하는 것은 해결책이 될 것입니다 (커밋되지 않은 격리 수준을 읽어)를 읽고 있지만 병합 문이 경우 다른 트랜잭션 원자와 볼 경우 내가 아무 생각이없는 경우
오라클은 커밋되지 않은 읽기를 허용하지 않습니다. –
얼마나 자주 충돌을 예상합니까?너무 자주 사용하지 않으면 테이블을 쿼리하는 함수 인 (bar, qux)에 대한 고유 제한 조건을 넣을 수 있습니다. no_data_found는 자 동 트랜잭션을 실행하여 삽입을 시도하고 제약 조건 핸들러 + 루프 (고정 재 시도 횟수)를 사용하여 충돌을 처리합니다. –
장기 실행 트랜잭션은 필자가 사용 해본 RDBMS에서는 확실한 no-no입니다. –