我编写的代码解析了一个文件,该文件包含要在Oracle表中更新的MAC地址和标志值。但是,由于此过程将在数千条记录上运行,因此我希望将工作负载分开并同时更新数据库。我不确定实现这个的最好方法,因为我是并发的初学者。我一直在阅读并查看示例代码,但对我来说仍然非常含糊不清。
我的第一个想法是将列表拆分为10个段,但它变得过于复杂,并且与列表列表和排序错综复杂......
我只是想朝着正确的方向努力......
附件是我目前的代码:
import java.io.*;
import java.util.*;
import java.text.ParseException;
import java.text.ParseException;
import java.lang.String;
import java.sql.*;
import java.lang.Class;
import oracle.jdbc.*;
import oracle.jdbc.driver.OracleDriver;
public class Process{
public FlagProcess(){
running = false;
}
public static List<String> readFile(String filename) throws IOException {
BufferedReader macAddresses = null;
List<String> info = new ArrayList<String>();
try {
macAddresses = new BufferedReader(new FileReader(filename));
String line = null;
while ((line = macAddresses.readLine()) != null) {
//Process the data, here we just print it out
System.out.println(line);
String[] bufferArray = line.split("\\|");
String mac = bufferArray[0];
String value = bufferArray[1];
System.out.println("MAC: " + mac);
System.out.println("PPV Value: " + value);
info.add(mac);
info.add(value);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} finally {
//Close the BufferedReader
try {
if (macAddresses != null)
macAddresses.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return info;
}
public static Connection getConnection() throws SQLException,ClassNotFoundException{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
String URL = "jdbc:oracle:thin://@xxxxxxxxxx:1521:xxxxxx";
Connection conn = DriverManager.getConnection(URL, "username", "password");
System.out.println("Connection established...");
return conn;
}
public static void freeConnection(Connection conn) throws SQLException {
try {
if (conn != null) {
conn.setAutoCommit(true);
}
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
System.out.println("FlagProcess.freeConnection() - got exception while closing connection.");
e.printStackTrace();
}
}
}
}
public static synchronized void updateDatabase(String mac, String value, Connection conn) throws SQLException
{
String update = "UPDATE device set FLAG = ? where IDENTIFICATION = ?";
System.out.println(update);
try{
PreparedStatement pstmt = conn.prepareStatement(update);
pstmt.setString(1, value);
pstmt.setString(2, mac);
int x = pstmt.executeUpdate();
System.out.println("Update complete.");
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
freeConnection(conn);
}
}
public static void main(String [] args){
PPVFlagProcess pfp = new PPVFlagProcess();
try{
List<String> info= readFile("values");
String mac = info.get(0);
String value = info.get(1);
Connection conn = pfp.getConnection();
pfp.updateDatabase(mac, value, conn);
pfp.freeConnection(conn);
}
catch(Exception e){
e.printStackTrace();
}
}
}
非常感谢任何帮助,谢谢。
答案 0 :(得分:3)
这听起来像对我来说过早优化。使用并发方法可以提高客户端的性能。但我希望你的瓶颈在数据库端(网络,数据库CPU,锁争用,光盘io)。使用并发方法甚至可能导致性能下降。
因此,如果你想快速得到这些东西,我会研究sqlldr和东西。
在此之前:获得一个简单的解决方案,然后寻找瓶颈。
答案 1 :(得分:1)
我无法在代码中看到任何并发性,如果您想要更好的性能,在预准备语句上设置批量大小,并且一次执行语句(例如在20条记录之后)。
答案 2 :(得分:1)
如果您担心代码的性能,首先要摆脱自动提交。您明确将其设置为true((残酷的)默认值)。通过将autocommit设置为false,您的代码已经快得多。
接下来要做的是使用批量加载。请参阅23 Performance Extensions,使用Oracle方式执行批处理,而不是标准方式。这样做你可能会问自己:为什么我这么做很难。
在Oracle中有一些 不做的事情:
答案 3 :(得分:0)
我认为,通过执行多线程,你正在放慢洞的速度。请改用预准备语句和batchupdate。
如果表现很重要,System.out
是个坏主意。