2017-05-04 31 views
5

Mam problem: Mam tabeli T z jednej kolumny z unikalnośćwstawić do unikalnej kolumny samej wartości z dwóch sesji (Oracle)

CREATE TABLE T (ID NUMBER, 
       UNIQUE (ID)); 

Sesja 1 wykonanej wkładki w tej tabeli

INSERT INTO T(id) VALUES(1); 

sesja 2 próbuje scalić tę samą wartość do tej tabeli

MERGE INTO t 
USING (SELECT 1 col FROM dual) s 
    ON (t.id = s.col) 
    WHEN NOT MATCHED THEN 
INSERT (id) VALUES (col); 

W tym momencie sesja 2 jest zablokowana i oczekuje na zatwierdzenie lub wycofanie sesji 1. Teraz biegnę w Sesji 1

COMMIT; 

W tym momencie wystąpił błąd w Sesja 2

ORA-00001: UNIQUE naruszone

jest jakieś opcje jak mogę tego uniknąć?

P.S. Problem polega na tym, że mam INSERT w jakiejś tabeli i MERGE (używając UNIQUE kolumn w sekcji ON) przy tym samym stole. Ten INSERT i MERGE są wywoływane oddzielnie w dwóch różnych sesjach. I czasami MERGE spada z powodu opisanej wyżej sytuacji. Mam nadzieję, że opisałem to w sposób zrozumiały

+0

Wygląda na to, że te dwie sesje nie mogą być uruchamiane równolegle, mogą być uruchamiane sekwencyjnie i czekają na zakończenie sesji 1, a następnie uruchomienie sesji 2, czy to byłby problem? – dood

+0

Jak generowana jest wartość id, a co jest nie tak z "ORA-00001" –

+0

@Akadiusz Łukasiewicz, jak powiedziałem - ID to tylko przykład. W rzeczywistości mam ograniczenie UNIQUE na 3 kolumny. Zrobiłem 'INSERT' w sesji 1. Po tym uruchomię' MERGE' z tymi samymi wartościami, ale scalam te 3 unikalne kolumny w sekcji ON (tak w normalnej sytuacji MERGE przechodzi do sekcji "KIEDYKOLWIEK dopasowano" i działa z powodzeniem). Teraz MERGE oczekuje na zatwierdzenie sesji 1. Po zatwierdzeniu MERGE nie kontroluje klauzuli ON, po prostu próbuje wykonać INSERT (przechodzi do sekcji "WHEN NOT MATCHED") i wchodzi w ORA-00001. – Tatiana

Odpowiedz

0

Twój przykład stanowi podzestaw phantom reads problem. Phantom czyta, a twój problem jest tylko właściwością relacyjnych baz danych. Polecam przeczytanie rozdziału 7 Kleppmanna Designing Data-Intensive Applications.

opcje nie należy lekceważyć:

  1. Redesign aplikację z optimistic locks.
  2. Zmień database isolation level na SERIALIZABLE, co spowolni poszczególne transakcje i zmniejszy zdolność bazy danych do równoległego wykonywania transakcji.

Z mojego doświadczenia wynika, że ​​większość projektantów wybiera trzecią opcję życia z problemem. W zależności od twoich niefunkcjonalnych wymagań, może być lepiej, aby twoja aplikacja była prosta, a nie teoretycznie poprawna.

Powiązane problemy