Java中的多线程Oracle Update

时间:2012-02-28 18:19:12

标签: java sql multithreading oracle concurrency

我编写的代码解析了一个文件,该文件包含要在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();
    }   
}

}

非常感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:3)

这听起来像对我来说过早优化。使用并发方法可以提高客户端的性能。但我希望你的瓶颈在数据库端(网络,数据库CPU,锁争用,光盘io)。使用并发方法甚至可能导致性能下降。

因此,如果你想快速得到这些东西,我会研究sqlldr和东西。

在此之前:获得一个简单的解决方案,然后寻找瓶颈。

答案 1 :(得分:1)

我无法在代码中看到任何并发性,如果您想要更好的性能,在预准备语句上设置批量大小,并且一次执行语句(例​​如在20条记录之后)。

答案 2 :(得分:1)

如果您担心代码的性能,首先要摆脱自动提交。您明确将其设置为true((残酷的)默认值)。通过将autocommit设置为false,您的代码已经快得多。

接下来要做的是使用批量加载。请参阅23 Performance Extensions,使用Oracle方式执行批处理,而不是标准方式。这样做你可能会问自己:为什么我这么做很难。

在Oracle中有一些 不做的事情:

  1. 自动提交
  2. 连接/断开每个小工作元素
  3. 使用动态(无准备)SQL

答案 3 :(得分:0)

我认为,通过执行多线程,你正在放慢洞的速度。请改用预准备语句和batchupdate。

如果表现很重要,System.out是个坏主意。