2015-06-16 40 views
4

我有一個java 1.6應用程序,它使用批量插入在Oracle數據庫中使用jdbc驅動程序插入記錄。正如您在Statement對象中所瞭解的,有一個名爲executeBatch()的方法,我們將其用於批量更新。它有一個返回類型的int數組,其中有每個記錄的執行結果。但是如果出現錯誤,它也會拋出BatchUpdateException,我們也可以從中得到結果int數組。我的問題是在什麼樣的錯誤情況下,我應該期待BatchUpdateException,並且當我期待沒有拋出異常,但是對於某些記錄我會失敗。executeBatch在部分失敗的情況下的行爲

注意:問題特別針對Oracle JDBC。 爲了更清楚地說明,我已經看到在執行executeBatch()之後,我沒有得到BatchUpdateException,但是有些insert語句失敗。我的問題是關於在什麼情況下可能發生?

這是Statement.executeBatch()方法的返回javadoc。根據一般意見,當一個條目失敗時,執行拋出BatchUpdateException,那麼在這種情況下,我們可以期望返回數組失敗的一些條目。

 * @return an array of update counts, with one entry for each command in the 
*   batch. The elements are ordered according to the order in which 
*   the commands were added to the batch. 
*   <p> 
*   <ol> 
*   <li> If the value of an element is >=0, the corresponding command 
*   completed successfully and the value is the update count for that 
*   command, which is the number of rows in the database affected by 
*   the command.</li> 
*   <li> If the value is SUCCESS_NO_INFO, the command completed 
*   successfully but the number of rows affected is unknown. 
*   <li> 
*   <li> If the value is EXECUTE_FAILED, the command failed. 
*   </ol> 
* @throws SQLException 
*    if an error occurs accessing the database 
*/ 
public int[] executeBatch() throws SQLException; 
+0

定義「對於我失敗的某些記錄」。例如,如果您進行更新,那麼沒有受影響的行不是失敗,它只是意味着沒有行被更新。 –

+0

這裏我只是插入語句。所以我沒有看到數據庫中的一些記錄,但我沒有看到任何異常跟蹤。 – cacert

+0

@cacert,你的插入有一個where子句,防止雙重插入?我在想'像WHERE NOT EXISTS(...)' –

回答

0

假設您有5個批量更新語句。他們每個人的執行是更新20個記錄,事先已知。

該批更新語句的執行發生時沒有引用BatchUpdateExceptionSQLException

如果返回的int數組中的任何元素不是20,那麼您知道存在意外行爲。這可能被視爲失敗。

編輯

從BatchUpdateExcpetion的JavaDoc(亮點是我的加法)

後在批量更新中的命令無法正確執行和 的BatchUpdateException被拋出,驅動程序可能會或可能不會繼續到 處理批處理中的其餘命令。如果驅動程序在故障發生後繼續執行 處理,則方法 BatchUpdateException.getUpdateCounts返回的數組將在批處理中爲每個 命令都有一個元素,而不是僅在 錯誤發生之前執行的命令的元素。在驅動程序 停止[ed]處理命令的情況下, 失敗的任何命令的數組元素是Statement.EXECUTE_FAILED。

我從這個理解是,如果批處理中的任何聲明失敗,那麼一個BatchUpadteException將被拋出。

+1

問題是*在什麼錯誤的情況下,我應該期待BatchUpdateException,當我應該期望沒有異常拋出,但對於一些記錄我得到失敗*。你在答案中所陳述的內容雖然不明確,但已經在問題中。 – Blip

+0

@Blip,添加更多我的答案。 –

+0

「我的理解是,如果批處理中的任何語句失敗,則會拋出BatchUpadteException異常。」其實我也在期待這一點,今天我得到一個錯誤,並得知事實並非如此。我期待一些關於什麼樣的失敗不會導致異常的澄清。今天我確信有這種情況。 – cacert

0

如果在批處理中發生錯誤,Oracle JDBC驅動程序將拋出BatchUpdateException。

例如,假設您發送一個包含10個條目的批次(10行,以便插入您的案例)。條目#0到#4是成功的。條目#5遇到錯誤,如主鍵違規。執行停止在5,驅動程序拋出BatchUpdateException。如果你調用getUpdateCounts(),你將得到一個大小爲10的數組,其中5個SUCCESS_NO_INFO和5個EXECUTE_FAILED。

請注意,從12c(數據庫和驅動程序)開始,您可以獲得該批次的每個元素的更新計數。當您批量執行更新時,這更有用。對於批次中的每個元素,您可以知道已更新了多少行。

+0

正如我所說的問題,我的問題是,雖然我沒有得到任何異議,我不能看到一些記錄沒有插入。可能是executeUpdate()爲未插入記錄返回錯誤,但代碼不處理該錯誤。我的問題是它在什麼情況下拋出錯誤,以及在什麼情況下它不會拋出錯誤,而是將失敗的標誌記錄。 – cacert

+0

如果批處理中的某個元素無法執行,executeBatch()將始終引發異常。這是根據JDBC規範。 –

相關問題