2012-07-26 101 views
1
則ExecuteBatch呼叫保證原子操作

我有以下的域對象:JDBC通過內的PreparedStatement

class Cat 
{ 
    String name; 
    int age; 
} 

和下面的語句做貓的批量插入:

void insertBulkCats(Collection<Cat> cats) 
{ 
    Connection conn = getConnection(); 
    PreparedStatement statement = new PreparedStatement(); 
    for(Cat cat : cats) 
    { 
     statement.setString(1, cat.getName()); 
     statement.setInt(2, cat.getAge()); 
     statement.addBatch(); 
    }  
    statement.executeBatch(); 
    PreparedStatement mergeStatement = conn.prepareStatement(MERGE_CATS); 
    mergeStatement.execute(); 
    PreparedStatement dropStatement = conn.prepareStatement(CLEAR_CATS);  
    dropStatement.execute(); 
    conn.commit(); 
} 

這是一個甲骨文數據庫。由於我想要執行的步驟是插入所有貓,對我的存檔貓進行合併,然後刪除插入的原始貓的所有記錄。我擔心的是,上述方法並不能保證發生回滾或單獨操作。我的問題是我如何保證這一切都作爲一個原子操作來執行?另外,如何保證沒有其他函數觸及數據庫(對Cat表進行更新),而不是讀取數據?

+0

你知道你必須執行你的'mergeStatement'和'dropStatement',不只是準備它們,對嗎? – Olaf 2012-07-26 12:58:31

+0

@Olaf是的,我忘了包括那個,因爲我正在用手抄錄,顯然沒有一張名爲Cat的表格。更新:) – Woot4Moo 2012-07-26 13:02:14

回答

7

原子性是ACID DBMS的一項功能。它在Oracle中是自動的:一旦完成提交,就運行所有的DML(更新/插入/刪除)。您保證操作將被保存爲不可分割的事務(如果提交失敗,則不會保存任何內容)。

在JDBC中,您必須確保關閉自動提交

關於併發性,它也是大多數數據庫管理系統的集成功能,儘管主要數據庫管理系統的鎖定行爲可能不同。

在Oracle寫入不要阻止讀取,但其他事務將不會看到您的更改,直到您提交:此隔離通過multi-versionning實現。 DML的鎖定機制處於行級別。只有一個事務可以同時修改一行。 Oracle在工作單元中的常見模式爲:

  1. 選擇要使用子句FOR UPDATE修改的行。這會對行進行鎖定,其他事務將不能修改這些行,直到您提交或回滾。
  2. 做你所有的DML沒有中間承諾
  3. 提交成功或在出現錯誤時回滾。

欲瞭解更多信息:更多關於transaction management,更多關於concurrency and locking

在Oracle中鎖定整個表格很少見,儘管這是一種可能性。可以使用LOCK TABLE命令來阻止其他會話對整個表的任何修改。

+0

有趣。在關閉自動提交方面,以某種方式在語句中設置的位置或Connection對象? – Woot4Moo 2012-07-26 13:11:00

+0

使用['Connection.setAutocommit'](http://docs.oracle.com/javase/6/docs/api/java/sql/Connection.html#setAutoCommit(boolean)) – 2012-07-26 13:17:08

+0

感謝您的回答。 – Woot4Moo 2012-07-26 13:21:05

相關問題