1

私は接続プーリングに Apache dbcp を使用し、Spring サポートでデータベース トランザクションを実行するために ibatis を使用しています。私がワークアウトしようとしているシナリオは次のとおりです。

  1. 最大初期接続を 5 として BasicDataSource を作成します

  2. 一時テーブルを作成する

  3. 一時テーブルに大量のレコードを書き込みます。
  4. レコードを実際のテーブルに書き込みます。

  5. 一時テーブルを削除する

ここでの問題は、ステップ 2 ~ 5 がマルチスレッド モードで実行されることです。また、接続プールを使用しているため、ステップ 2、3、4、5 がプールから同じ接続オブジェクトを取得することを保証できません。したがって、ステップ 3/4/5 で、一時テーブル XYZ が見つからないことがわかります。

4 つの操作で同じ接続を再利用できることを保証するにはどうすればよいですか。ステップ 3 と 4 のコードは次のとおりです。グローバル一時テーブルを使用することは考えていません。

@Transactional  
public final void insertInBulk(final List<Rows> rows) {  
getSqlMapClientTemplate().execute(new SqlMapClientCallback<Object>() {  
    public Object doInSqlMapClient(  
        SqlMapExecutor exe) throws SQLException {  
            executor.startBatch();  
            for (Rows row : rows) {  
                for (Object row : row.getMultiRows()) {  
                    exe.insert("##TEMPTABLE.insert", row);  
                }  
            }  
            exe.executeBatch();  
            return null;  
     }});  

}

public void copyValuesToActualTable() {  
    final Map<String, Object> procInput = new HashMap<String, Object>();  
    procInputMap.put("tableName", "MYTABLE");  
    getSqlMapClientTemplate().queryForObject("##TEMPTABLE.NAME", procInput);  
}  

接続が初期化されたときに一度だけ一時テーブルを作成し、後でテーブルを切り捨てるのではなく、ステップ 3 と 4 でまだ問題が発生するようにすることで、設計をさらに改善することを考えています。一時テーブルの理由は、アクセスできないためです (パーミッション) 実際のテーブルを直接変更しますが、一時テーブルを介して変更します。

4

1 に答える 1

0

メイン スレッドで実際に一時テーブルを作成し (ステップ 2)、一時テーブルにレコードを挿入するワークロード (ステップ 3 とステップ 4) をチャンクに分割し、チャンクごとにスレッドを生成します。

JDK 7 は、興味のあるこのステップのForkJoinを提供します。

一時テーブルと実際のテーブルへの挿入が完了したら、メイン スレッドで一時テーブルを再度削除します。

この方法では、どこでも同じ接続が使用されていることを確認する必要はありません。同じデータベースに対して異なる接続オブジェクトを使用して、ステップ 3 と 4 を並行して実行できます。

お役に立てれば。

于 2012-08-25T10:50:26.607 に答える