Многопоточное обновление Oracle в Java - PullRequest
0 голосов
/ 28 февраля 2012

Я написал код, который анализирует файл, который содержит MAC-адреса и значения флагов для обновления в таблице Oracle.Однако, поскольку этот процесс будет выполняться на тысячах записей, я хочу разделить рабочую нагрузку и обновить базу данных одновременно.Я не уверен в наилучшем способе реализации этого, поскольку я новичок в параллелизме.Я читал и просматривал пример кода, но он все еще очень неоднозначен и неясен для меня.

Моя первая идея состояла в том, чтобы разбить список на 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 ]

3 голосов
/ 28 февраля 2012

Для меня это звучит как преждевременная оптимизация. При параллельном подходе вы повысите производительность на стороне клиента. Но я ожидаю, что ваше узкое место будет на стороне базы данных (сеть, процессор базы данных, конфликт блокировки, диск io). При параллельном подходе это может привести к снижению производительности.

Так что, если вы хотите быстро разобраться с этим, я бы посмотрел на sqlldr и все такое.

И прежде всего: найдите простое решение и найдите узкое место.

1 голос
/ 29 февраля 2012

Если вы беспокоитесь о производительности своего кода, начните с избавления от автоматической фиксации. Вы явно устанавливаете для него значение true ((жестокое) по умолчанию). Ваш код уже будет намного быстрее, если установить для autocommit значение false.

Следующее, что нужно сделать, это использовать массовую загрузку. См. 23 Performance Extensions , используйте способ Oracle для выполнения пакетов, а не стандартный способ. Сделайте это, и вы можете спросить себя: почему я сделал это так сложно.

В Oracle есть несколько что нельзя делать:

  1. автокоммит
  2. подключение / отключение для каждого небольшого элемента работы
  3. использовать динамический (неподготовленный) SQL
1 голос
/ 28 февраля 2012

Я не вижу параллелизма в вашем коде, если вы хотите повысить производительность, установить размер пакета в подготовленном операторе и выполнять операторы время от времени (например, после 20 записей).

0 голосов
/ 28 февраля 2012

Я думаю, вы замедляете дырку, выполняя ее многопоточно. Вместо этого используйте подготовленные заявления и пакетное обновление.

System.out - плохая идея, если важна производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...