Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[JAVA] Concurrency probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Er treedt een concurrency probleem op a.d.h.v. de 2 onderstaande klassen. Vermoedelijk moet de methode getConnection aangepast worden zodat er elke keer een nieuwe connectie wordt aangemaakt in plaats van te werken met de statische variabele. Wie kan hier mee helpen of heeft een beter voorstel?

Java:
1
2
3
4
5
6
7
8
public class Connector {
    private static final String DB_NAME = "jdbc:odbc:test";
    
    private static Connection conn = null;
    
    public static Connection getConnection() {
        return getConnection(DB_NAME);
    }


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static Connection getConnection(String dbUrl) {
        try{
            if(conn == null || conn.isClosed()){
                synchronized (Connector.class) {
                    if(conn == null || conn.isClosed()){
                        try{
                            // Load the JDBC-ODBC bridge driver used
                            // for connecting to an ODBC data source...
                            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                
                            // Retrieve a connection to the database...
                            conn = DriverManager.getConnection(dbUrl);
                            
                          
                
                        }catch(ClassNotFoundException cnfe){
                            System.err.println("ClassNotFoundException "+cnfe.getMessage());
                        }catch(SQLException se){
                            System.err.println("SQLException "+se.getMessage());
                        }catch(NullPointerException npe){
                            System.err.println("NullPointerException "+npe.getMessage());
                        }catch(Exception e){
                            System.err.println("Exception "+e.getMessage());
                        }
                    }
                }
            }
        }
        catch(SQLException se){
            System.err.println("SQLException "+se.getMessage());
        }
        return conn;
    }

}

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Waarom declareer je een connection (een dure resource met een beperkte levensduur) in vredesnaam static?

edit:
Voor de duidelijkheid, er is hier helemaal geen sprake van een cuncurrency probleem en die double checked locking is ook compleet overbodig. Je bewaart een resource met een beperkte levensduur in een static variabele. Zodra de connectie aan het eind van haar levensduur is heb je een groot probleem. Een connectie zou direct vóór het uitvoeren van de statement moeten worden verkregen en direct ná het verwerken van de statement cq resultaat moeten worden gesloten. Je zou ook aan connection pooling kunnen denken zodat de connecties binnen een bepaalde timeout herbruikt kunnen worden hetgeen resulteert in een betere performance. Veel JDBC drivers en applicatieservers ondersteunen connection pool datasources.

Het laden van de driver kun je wel éénmaal gedurende de levensduur van de applicatie doen, dat hoef je niet elke keer te doen bij het verkrijgen van een connectie en het laden ervan is ook niet nodig bij het gebruik van datasources, dat doet de datasource wel zelf.

[ Voor 86% gewijzigd door BalusC op 10-12-2007 13:56 ]


  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

En je weet ook dat de JDBC:ODBC bridge niet thread safe is?

With the light in our eyes, it's hard to see.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Een paar improvements:

1) ipv met een statische variable te werken, maak gebruik van een member variable. Dito geld voor die getconnection methode. State bewaren in statische velden is meestal (niet altijd) een mindere oplossing.

2) Ik zou de methode 'getConnection' gewoon synchronized maken, of een init methode maken waarvan je kunt garanderen dat die wordt aangeroepen. Op die manier zal je object na constructor niet meer van toestand veranderen en is de kans groot dat je het in principe immutable is. Immutable objecten hebben veel minder behoefte aan synchronisatie. En verder ben je dan ook af van die vage double checked locking (zoals BalusC al aangaf).

3) Waarom synchroniseer je op de class van de Connector

4) Ik zou gebruik maken van een connectie pool. Een connectie delen is meestal niet zo handig als je die door meerdere threads tegelijk wilt laten gebruiken. Iedere thread moet zijn eigen connectie hebben en na afloop de connectie weer terug brengen naar de pool (zoals BalusC al aangaf).