2011-01-18 18 views
9

Mam aplikację, która przetwarza bardzo duży plik i wysyła dane do bazy danych Oracle (używając Java 6, Oracle 9).BatchUpdateException: partia nie zakończy się

W pętli używam PreparedStatement ps i tworzę wszystkie instrukcje SQL wygenerowane przy pomocy ps.addBatch().

Mam sytuację, w której BatchUpdateException bue jest wyrzucany gdzieś podczas ps.executeBatch(). W tym momencie partia przestaje być wykonywana.

Chciałbym, aby kontynuowanie wykonywania wsadu było kontynuowane, aby można było następnie sprawdzić nieudane aktualizacje w metodzie processUpdateCounts(bue.getUpdateCounts()).

Javadoc o klasie BatchUpdateException mówi:

Po komendzie w aktualizacji wsadowym nie prawidłowo wykonać i BatchUpdateException jest wyrzucane, kierowca może lub nie może kontynuować do procesu pozostałe polecenia w grupie wsadowej .

Czy istnieje sposób na wymuszenie kontynuacji lub czy muszę zmienić mój program tak, aby wykonywał oświadczenie indywidualnie?

Odpowiedz

5

tylko znaleźć ten link: JDBC Batch Update Problem

Widocznie, to mówi, że tam jest

NO WAY z Oracle JDBC SERII postępować po pierwszym niepowodzeniu,

W ten sposób uciekam się do wysyłania insertów jeden po drugim. Dziękujemy

(przepraszam, że nie wygląda lepiej znaleźć powyższy link wcześniej).

0

Ponieważ specyfikacja nie wydaje się, aby to zlecić (jak wyraźnie pokazano przez Javadoc), każda "wymuszona" kontynuacja musiałaby być wykonywana dla każdego kierowcy. Prostym rozwiązaniem zgodnym z normą byłoby sprawdzenie zwróconej tablicy i "ponowne uruchomienie" partii dla tych instrukcji, które nie powiodły się. Możesz uczynić to podejście nieco bardziej wyrafinowanym, wprowadzając logikę określającą liczbę ponownych prób.

Oczywiście, wydaje się to trochę kłopotliwe (śledzenie "partii" dodanej, a następnie sprawdzanie danych wyjściowych), ale działałoby we wszystkich bazach danych i implementacjach sterowników. Tylko myśl ...

3

Istnieje obejście, które umożliwia korzystanie z funkcji wsadowej. Zamiast wykonywać proste INSERT, można wykonać PL blok/SQL, który zajmie się błędu odpowiednio miejsca:

BEGIN 
    INSERT INTO your_table VALUES (?,?,...?); 
EXCEPTION 
    WHEN OTHERS THEN 
     /* deal with the error. For example, log the error id and error msg 
     so that you can list them after the batch */ 
     INSERT INTO error_table VALUES (?, sqlerrm); 
END 

Występ powinien być na równi z wkładką wsadowym (powinno być szybsze niż indywidualne wykonanie z sprawozdania). Można również wywołać procedurę przechowywaną zamiast bloku PL/SQL.

1

sam Oracle można znaleźć tutaj: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci04sql.htm#sthref616

Jednak nie wydaje się, że ta funkcja jest narażona na JDBC, nawet w klasach określonych Oracle.

Z powodu dość bezużytecznej obsługi błędów JDBC ("sterownik może lub może nie być kontynuowany"), zawsze ustawiam punkt zapisu przed partią i wykonuję wycofanie do tego punktu błędu. To jedyny zgodny z JDBC sposób ustanowienia znanego stanu po błędzie Oracle Batch - o ile wiem.

Powiązane problemy