2016-05-13 69 views
0

我正在使用多个线程将数百万条记录插入到数据库中。 我正在使用3个课程。如何在多线程中使用连接池?

的getConnection

import java.sql.Connection; 
import java.sql.SQLException; 
import org.apache.commons.dbcp2.BasicDataSource; 
import LoadConfig; 
public class DBCP { 
    private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("DBCP"); 
    private Connection conn; 
    public static Connection getOracleConnection() throws SQLException, 
     ClassNotFoundException { 
    String hostName = LoadConfig.Getconfig("hostName"); 
    String sid = LoadConfig.Getconfig("sid"); 
    String userName = LoadConfig.Getconfig("userName"); 
    String password = LoadConfig.Getconfig("password"); 

    return getOracleConnection(hostName, sid, userName, password); 
} 

    private static Connection getOracleConnection(String hostName, String sid, String userName, String password) 
      throws SQLException { 
     BasicDataSource dataSource = new BasicDataSource(); 
     try 
     { 
      dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); 
      dataSource.setUrl("jdbc:oracle:thin:@" + hostName + ":1521:" + sid); 
      dataSource.setUsername(userName); 
      dataSource.setPassword(password); 
      dataSource.setMaxTotal(300); 
      return dataSource.getConnection(); 
     } catch (SQLException ex) { 
      log.error("SQLException"+ex); 
      return null; 
     } 
    } 
} 

阅读的文本

public class Readtxt implements Runnable{ 
    private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("ReadFile"); 
    File file = new File(path); 
    ExecutorService executor = Executors.newFixedThreadPool(100); 


    @Override 
    public void run() { 
     try { 
      Connection conn = data.getOracleConnection() 
      try (BufferedReader br = new BufferedReader(new FileReader(file.getAbsolutePath()))) { 
       String line; 
       int i=0; 
       log.info("Start read and update file: " + fileName); 
       while ((line = br.readLine()) != null) { 
        Runnable Insert = new InsertDT(conn, line); 
        executor.execute(Insert); 
       } 
       log.info("Finish reading: " + fileName); 
      } catch (IOException ex) { 
       log.fatal("ReadFile IOException: " + ex); 

     } catch (Exception ex) { 
      log.fatal("Connect Error: " + ex); 
     } 
    } 
} 

插入类

public class InsertDT implements Runnable{ 
    private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("InsertDT"); 
    private String line 
    Connection conn = null; 
    CallableStatement statement; 
    public InsertDT(Connection _conn, String _line){ 
      this.conn = _conn; 
      this.line = _line; 
    } 
    @Override 
    public void run() { 
     try { 
      try { 
       this.statement = conn.prepareCall("{ Call Produce (?,?)}"); 
       statement.setString("Data", line); 
       statement.executeUpdate(); 
      } catch (Exception ex) { 
      } 
     } catch (SQLException | ClassNotFoundException ex) { 
      log.error(ex); 
     } 
    } 

} 

但是亲ject需要很多时间才能将记录插入数据库。有没有人有任何想法如何解决这个问题?

+1

尝试批量插入而不是一次插入一个 – sidgate

回答

0

首先对于您正在构建的每个读线程datasource

Connection conn = data.getOracleConnection() 

单身数据源很好。您将在应用程序启动时构建并在每次从您的Factory实施中需要时使用它。

其次你分享相同的connection你从datasource得到。

Runnable Insert = new InsertDT(conn, line); 

这是最好的分配单独connection每个thread。因此,每次您提及相同的datasource并获得新的connection,并将其交给每个线程使用。

更重要的是,你的线程池有多大以及你分配了多少并发线程并不重要;所有重要的是CPU core