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