2016-05-13 3 views
0

Ich verwende mehrere Threads, um Millionen von Datensätzen in die Datenbank einzufügen. Ich verwende 3 Klassen.Wie verwende ich den Verbindungspool in Multi Thread?

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

lesen Text:

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

und Insert Klasse:

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

} 

Aber die Pro Es dauert viel Zeit, um Datensätze in die Datenbank einzufügen. Hat jemand eine Idee, wie man das beheben kann?

+1

versuchen Batch-einfügen statt einzeln nacheinander – sidgate

Antwort

0

Zuerst für jeden gelesenen Thread, den Sie bauen datasource.

Connection conn = data.getOracleConnection() 

Es ist gut, Singleton Datenquelle zu haben. Welche Sie während der Anwendung erstellen werden und verwenden Sie sie jedes Mal, wenn Sie sie von Ihrer Factory Implementierung benötigen.

Zweitens teilen Sie die gleiche connection, die Sie von datasource erhalten haben.

Runnable Insert = new InsertDT(conn, line); 

Es ist am besten getrennt connection für jeden thread zuzuordnen. Also jedes Mal, wenn Sie auf das gleiche beziehen datasource und erhalten Sie eine neue connection und geben Sie es jedem Thread damit zu arbeiten.

Mehr darüber ist nicht wirklich wichtig, wie groß ist Ihr Thread-Pool und wie viele gleichzeitige Thread Sie zugewiesen haben; Alles, was zählt, ist die CPU core.