1

我正在使用 Apache dbcp 进行连接池,并使用 ibatis 在 Spring 支持下进行数据库事务。我正在尝试锻炼的场景是:

  1. 创建最大初始连接为 5 的 BasicDataSource

  2. 创建临时表

  3. 在临时表中写入大量记录。
  4. 将记录写入实际表中。

  5. 删除临时表

这里的问题是步骤 2-5 在多线程模式下运行。此外,由于我正在使用连接池,我不能保证 sttep 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 回答