Avatar billede trophymanager Nybegynder
27. marts 2006 - 11:59 Der er 19 kommentarer og
3 løsninger

Overload af connections?

Hej Alle.

Jeg har et javaprogram der kører nogle opdateringer i en database. Det drejer sig om en main klasse jeg eksekverer der så kører x antal gange - hver gang laver den en connection til en database og henter noget data ind. I main klassen bliver der også kørt en anden klasse der tilsvarende opretter forbindelse. Jeg har renset lidt ud i koden og skelettet for de to klasser ses her:


//Main class

ResultSet rs = null;

try Class.forName("com.mysql.jdbc.Driver");
catch(Exception e)     System.out.println(e.getMessage());

while (blabla) {
           
    try {
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost/database", "login", "password");  <--- Fejlen peger på denne linie.
        Statement stmt = con.createStatement();
       
          rs = stmt.executeQuery("SELECT * FROM table WHERE id>"+x+" ORDER BY id LIMIT 1");

        while(rs.next()) {
           
            rs = stmt.executeQuery("SELECT * FROM players WHERE klub =" + teamId + "");

            while(rs.next()) {
         
                try stmt.executeUpdate("UPDATE table SET values");
                catch(Exception e) System.out.println(e);
            }
        }
           
    } catch(Exception e) System.out.println(e);
}

// Klasse der bliver kaldt inde i main hver gang.

    public Trainer(int t, int teamId) {
        team = t;
       
        try {
            Class.forName("com.mysql.jdbc.Driver");

            Connection con = DriverManager.getConnection("jdbc:mysql://localhost/database", "login", "password");
            Statement stmt = con.createStatement();
       
            rs = stmt.executeQuery("SELECT * FROM table LIMIT 1");
           
            while (rs.next()) {
                               
            }
           
           
        } catch (Exception e) {
           
        }
       
    }


Mit problem er at sidst jeg kørte dette opstod der denne fejl http://www.trophymanager.com/javafejl.gif hvor der bliver peget på den første connection i main klassen som problemet. Det skete forholdsvis konsekvent efter hvert 600-650 gennemløb. Her stoppede javaprogrammet og databaseserveren gik kort ned. Jeg ved ikke hvilken rækkefølge. Hvis der er nogen der har noget hjælpe til at forhindre dette vil det være meget belejligt. På forhånd tak.
Avatar billede mikkelbm Nybegynder
27. marts 2006 - 12:09 #1
Prøv at flytte din connection udenfor while-løkken.
Avatar billede arne_v Ekspert
27. marts 2006 - 13:55 #2
enten getConnection og createStatement udenfor den yderste while løkke

eller close statement og connection i bunden af while løkken

det første performer bedst

normalt klarer Java garbage collection den slags, men i sådan en løkke er det vigtigt
at close eksplicit
Avatar billede trophymanager Nybegynder
27. marts 2006 - 14:54 #3
hvordan ville det se ud hvis jeg skulle lukke selv?
Avatar billede mikkelbm Nybegynder
27. marts 2006 - 14:55 #4
con.close();
Avatar billede javaisnice Nybegynder
29. marts 2006 - 11:59 #5
hvis jeg var dig ville jeg lave en singleton connection til databasen - så undgår du, at der er to forbindelser på samme adresse.
Avatar billede trophymanager Nybegynder
29. marts 2006 - 12:02 #6
Har du nogen stedet jeg kan læse mere om dette?
Avatar billede mikkelbm Nybegynder
29. marts 2006 - 12:09 #7
http://javabog.dk/VP/kapitel16.jsp

Men hvordan går det ellers med at løse problemet?
Avatar billede javaisnice Nybegynder
29. marts 2006 - 12:38 #8
Nedenstående er et eksempel på en singleton database connection, når du skal bruge forbindelsen skal du blot foretage dette kald: DataBaseConnection.getInstance().getConnection();

package control;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
*
* @author Michael Dipo
*/
public class DataBaseConnection {
    private static DataBaseConnection INSTANCE = new DataBaseConnection();
    private Connection conn = null;
    public static DataBaseConnection getInstance(){
        return INSTANCE;
    }
    /** Creates a new instance of DataBaseConnection */
    private  DataBaseConnection() {
        try{
            Class.forName("org.gjt.mm.mysql.Driver");
           
        } catch (ClassNotFoundException cnfe){
            System.err.println("ClassNotFound"+ cnfe);
        }
        String host = "localhost";
        String dbName = "test";
        int port = 3306;
        String uName = "root";
        String pWord = "michael";
        try{
            conn = DriverManager.getConnection("jdbc:mysql://"+host+"/"+dbName+"?user="+uName+"&password="+pWord);
//            conn.close();
        } catch (SQLException SQLE){
            System.out.println("SQLException" + SQLE);
        }
       
    }
    public Connection getConnection(){
        return conn;
    }
   
}
Avatar billede arne_v Ekspert
29. marts 2006 - 13:21 #9
Avatar billede arne_v Ekspert
29. marts 2006 - 13:24 #10
singleton bør kun bruge til database connection hvis:
  - en connetion er nok til performance krav
  - klassen har synkroniserede metoder til alle operationer
ellers skyder man hurtigt sig selv i foden.
Avatar billede trophymanager Nybegynder
29. marts 2006 - 13:24 #11
re mikkel - jeg flyttede min connection uden for lykken og det gav mig ca 100 loops mere inden samme problem opstod. Nu prøver jeg lige at omskrive hele balladen ud fra de inputs I har givet mig og vender tilbage torsdag eller fredag med en forhåbentlig glad meddelelse :)

Indtil videre tak for hjælpen til alle. Det er dejligt I gider komme med indspark.
Avatar billede trophymanager Nybegynder
29. marts 2006 - 13:26 #12
Arne kan du eventuelt uddybe dette? Hvornår er det ikke godt at bruge det?
Avatar billede arne_v Ekspert
29. marts 2006 - 13:32 #13
hvis du har brug for parallelt løbende queries

eller

hvis klassen returnerer en connection som frit kan bruges (fordi hvis
2 tråde så bruger den samme connection, så bang ...)
Avatar billede trophymanager Nybegynder
29. marts 2006 - 13:38 #14
ah ok - det er en rimelig simpelt proces jeg har gang i - den kører bare mange gange. Vil der være nogen problemer i en struktur som denne:

rs = bla bla bla

while (rs.next()) {

    rs1 = bla bla bal

    while (rs1.next()) {

     
    }

}

hvis man bruger singleton?
Avatar billede javaisnice Nybegynder
29. marts 2006 - 13:42 #15
arne har ret...metoderne bør være synkroniserede. fordelen ved singleton klassen er selvfølgelig, at vi ikke behøver at åbne og lukke forbindelsen 600 gange eller hvor meget der nu er nødvendigt.
Avatar billede arne_v Ekspert
29. marts 2006 - 13:45 #16
det kan man løse ved at bruge en connection pool
Avatar billede javaisnice Nybegynder
29. marts 2006 - 13:50 #17
Hvis vi taler performance/database-connections i mange tråde vil det jo nok også være smartest med en connectionpool, men det vil mildest talt være overkill i dette tilfælde tror jeg.
Avatar billede arne_v Ekspert
29. marts 2006 - 14:35 #18
det er ihvertfald ikke nødvendigt

med hensyn til overkill så bruger man i .NET altid connection pool medmindre
man eksplicit beder om ikke at bruge det
Avatar billede trophymanager Nybegynder
02. april 2006 - 00:28 #19
Der var sq pote. I havde alle en del af æren så dem der vil ha point smid et svar :)
Avatar billede mikkelbm Nybegynder
02. april 2006 - 00:32 #20
.
Avatar billede arne_v Ekspert
02. april 2006 - 00:33 #21
.
Avatar billede javaisnice Nybegynder
02. april 2006 - 22:21 #22
:-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester