1

次のドメインオブジェクトがあります。

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();
}  

これはOracleデータベースです。実行したい手順は、すべての猫を挿入し、アーカイブされた猫に対してマージを実行してから、挿入された元の猫からすべてのレコードを削除することです。私の懸念は、上記のこのアプローチは、ロールバックまたは単独の操作が発生することを保証するものではないということです。私の質問は、これがすべて1つのアトミック操作として実行されることをどのように保証するのですか?さらに、読み取りではない他の関数が(Catテーブルの更新を行うという観点から)データベースにアクセスしないことをどのように保証できますか?

4

1 に答える 1

8

AtomicityはACIDDBMSの機能です。Oracleでは自動です。コミットの発行が完了したら、すべてのDML(更新/挿入/削除)を実行します。操作は分割できないトランザクションとして保存されることが保証されます(コミットが失敗した場合、何も保存されません)。

JDBCでは、必ず自動コミットをオフにする必要があります。

同時実行性に関しては、ほとんどのDBMSの統合機能でもありますが、ロックの動作は主要なDBMS間で異なる場合があります。

Oracleでは、書き込みは読み取りをブロックしませんが、コミットするまで他のトランザクションは変更を認識しません。この分離は、マルチバージョン化によって実装されます。DMLのロックメカニズムは行レベルにあります。同時に行を変更できるトランザクションは1つだけです。Oracleの作業単位の一般的なパターンは次のとおりです。

  1. 句を使用して変更する行を選択しますFOR UPDATE。これにより行がロックされ、コミットまたはロールバックするまで、他のトランザクションはこれらの行を変更できなくなります。
  2. 中間コミットなしですべてのDMLを実行します
  3. 成功した場合はコミットするか、エラーが発生した場合はロールバックします。

詳細については、トランザクション管理の詳細、同時実行性とロックの詳細をご覧ください。

Oracleではテーブル全体をロックすることはまれですが、可能性はあります。LOCK TABLEコマンドを使用して、他のセッションからテーブル全体への変更を防ぐことができます。

于 2012-07-26T13:08:01.153 に答える