我必须从具有超过100K记录的ArrayList在DB中插入一些值。我正在使用下面给出的CountDownLatch和ExecutorService类来一次运行10个线程以提高插入时的性能。我正在调用一个Stored过程,在一些细节处理之后将Employee细节插入到两个不同的表中。这是否符合我的要求?
public static void writeData(List<Employee> empList) throws SQLException {
Connection con = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "oracle");
final CountDownLatch latch = new CountDownLatch(empList.size());
ExecutorService taskExecutor = Executors.newFixedThreadPool(10);
final CallableStatement cstmt = con.prepareCall("{Call Prc_Insert_Employee(?,?,?)}");
for (int i = 0; i < empList.size(); i++) {
final Employee emp = empList.get(i);
Thread worker = new Thread() {
public void run() {
try {
cstmt.setString(1, emp.getId());
cstmt.setString(2, emp.getName());
cstmt.setString(2, emp.getAge());
cstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally{
latch.countDown();
}
}
};
taskExecutor.execute(worker);
}
taskExecutor.shutdown();
latch.await();
} catch (Exception e) {
System.out.println(e);
} finally {
con.close();
}
}
答案 0 :(得分:1)
以下是我对您的代码所做的所有评论:
addBatch()
代替executeUpdate()
来减少数据库与应用程序之间的往返总量,它应该在性能方面有很大帮助,特别是对于远程数据库,也许你甚至不需要使用这种方法使用多个线程。 CallableStatement
是一种好习惯。我不认为它是线程安全的,您应该为每个线程使用专用的Connection
和CallableStatement
。connection.setAutoCommit(false)
来禁用自动提交模式,该模式并不意味着用于加载大量数据。这意味着您需要为每个x存储的记录显式调用connection.commit()
。Runnable
而不是Thread
,因为它是ExecutorService
所期望的。不需要在此处创建线程实例,因为ExecutorService
将Runnable
视为Runnable
,因此即使您向{{ExecutorService
提供了超过10个execute
个对象,您也只有10个线程1}}到Returns true if the stream has no errors occurred and is ready
of I/O operations. Specifically, returns !fail()
。启动有序关闭,其中执行先前提交的任务,但不接受任何新任务。