2009-11-05 10 views
21

sto provando a collegarsi al DB usando il modo standard JDBCtimeout di connessione per DriverManager getConnection

connection = DriverManager.getConnection(url, username, password); 

C'è un valore massimo di timeout sulla connessione, quanto tempo una connessione diretta, posso aumentare il valore . Voglio nei casi in cui la connessione sia aperta per sempre, è una buona idea.

risposta

24

Il valore è in genere controllato da DB. Non hai il controllo su di esso utilizzando il codice. Dipende dal server DB utilizzato. Di solito dura circa 30 minuti fino a un'ora.

D'altra parte, mantenere aperto il numero Connection per sempre è una pessima idea. Migliore pratica è acquisire e chiudere Connection, Statement e ResultSet nel più breve portata possibile per evitare perdite di risorse e potenziali crash dell'applicazione causati dalle perdite e timeout.

Vero, il collegamento del DB è un compito costoso. Se la tua applicazione dovrebbe funzionare relativamente a lungo e collegare il DB abbastanza spesso, allora considera di utilizzare un pool di connessioni per migliorare le prestazioni di connessione. Se la tua applicazione è un'applicazione web, dai uno sguardo alla documentazione di appserver, di solito fornisce una funzione di pool di connessioni nel sapore di un DataSource. Se si tratta di un'applicazione client, cercare le librerie di pool di connessioni di terze parti che hanno dimostrato la loro robustezza con anni, come ad esempio Apache Commons DBCP (comunemente utilizzato, in appserver di lotti), C3P0 (noto da Hibernate) e Proxool (se si desidera connessioni XA).

Ricordare che, quando si utilizza un pool di connessioni, è ancora necessario scrivere il codice JDBC corretto, ad es. acquisire e chiudere tutte le risorse nel più breve ambito possibile. A sua volta, il pool di connessioni si preoccuperà di chiudere effettivamente la connessione o di rilasciarla nuovamente al pool per un ulteriore riutilizzo.

È possibile ottenere ulteriori informazioni da this article come eseguire correttamente le basi JDBC.

Spero che questo aiuti e felice codifica.

+2

DBCP è un orribile, * orribile * pool di connessioni, mai usato – erickson

+0

Interessante. Non ho mai avuto seri problemi con esso se usato nel gusto di un'origine dati gestita da Tomcat 6.0.Ti cura di elaborare? – BalusC

+6

Bene, tu desidera utilizzare un pool quando le risorse sono "costose" (richiede un po 'di tempo per la creazione) DBCP (o il pool sottostante) mantiene un blocco sull'intero pool mentre vengono prodotti nuovi oggetti. Ciò impedisce che i thread abbiano finito con una risorsa e stanno semplicemente tentando di restituirlo al blocco. Nel frattempo, altri thread sono bloccati nel tentativo di ottenere quelle risorse .Perché queste acquisizioni di blocco non utilizzano il pacchetto simultaneo, non sono interrompibili.Questo fa male le prestazioni in condizioni normali. veramente stupido con il DB, diventa * veramente * brutto, veramente veloce – erickson

24

È possibile impostare il timeout sul DriverManager come questo:

DriverManager.setLoginTimeout(10); 
Connection c = DriverManager.getConnection(url, username, password); 

che implicherebbe che, se la connessione non può aprire entro il tempo determinato che il tempo è scaduto.

In termini di mantenere una connessione aperta per sempre, è possibile se non si chiude la connessione ma potrebbe non essere una buona idea. I collegamenti dovrebbero essere chiusi non appena hai finito con loro.

Se si desidera ottimizzare l'apertura e la chiusura delle connessioni, è possibile utilizzare un pool di connessioni.

+3

Hmm, IIRC imposta solo il timeout per il tempo in cui DriverManager deve attendere prima che il DB abbia restituito una connessione. Non imposta il timeout della connessione. Vedi anche: http://java.sun.com/javase/6/docs/api/java/sql/DriverManager.html#setLoginTimeout%28int%29 – BalusC

+1

Questo è giusto @BalusC. Come ho detto che il timeout è solo per quanto tempo il DriverManager aspetta una connessione, non per quanto tempo la connessione rimane aperta. –

+2

Devo tuttavia ammettere (e probabilmente anche tu) che questa è la risposta corretta alla domanda come letteralmente formulata nell'argomento dell'argomento. Ma la vera domanda nel messaggio di argomento si è rivelata essere qualcosa di diverso. – BalusC

5

Ecco come farlo con il driver Connector/J MYSQL:

String qqq = "jdbc:mysql://localhost/Test?connectTimeout=TIME_IN_MILLIS"; 
conn = DriverManager.getConnection(qqq, db_user, db_pass); 

Ha funzionato per me dopo setLoginTimeout() non ha fatto nulla.

+4

non funziona 'connectTimeout = TIME_IN_MILLIS' perché è' connectTimeout = TIME_IN_SECONDS' maggiori informazioni qui http://dev.mysql.com/doc/refman/5.1/en/mysql-command-options.html#option_mysql_connect_timeout – HCarrasko

0

È possibile utilizzare l'interfaccia ExecutorService da Java. Di seguito è riportato un esempio di ciò che devi fare.

Future<Boolean> future = executor.submit(YOUR_METHOD); 
future.get(TIMEOUT_YOU_NEED, TimeUnit.SECONDS); 
+0

Un'idea terribile . Questo crea un ThreadFactory, un Thread, esegue la connessione in parallelo e implementa un timeout in 'get()', lasciando la connessione effettiva per procedere senza un vero modo di abortire se stesso. – EJP

4

Basta reposting un repost più completo di un commento da flamming_python utente come risposta, perché ha funzionato per me:

dbConnectionString = "jdbc:mysql://"+dbHost+":"+dbPort+"/"+dbTable+"?user="+dbUser+"&password="+dbPassword; 
Properties properties = new Properties(); 
properties.put("connectTimeout", "2000"); 
dbConnect = DriverManager.getConnection(dbConnectionString, properties); 

commento originale:
"LOL @ le discussioni che - lo si può fare molto semplicemente creando un oggetto Proprietà prop, quindi prop.put ("connectTimeout", "2000") (dove "2000" è il timeout in ms), quindi passa il tuo oggetto prop al metodo DriverManager.getConnection() insieme a il tuo url "

0

A suggerito da bestro, è possibile utilizzare un futuro con un timeout associato. Ad esempio:

ExecutorService executor = Executors.newSingleThreadExecutor(); 
Future<Connection> future = executor.submit(new Callable<Connection>() { 

    @Override 
    public Connection call() throws Exception { 
     Connection con = DriverManager.getConnection(url, username, password); 
     return con; 
    } 
}); 

Connection con = null; 
try { 
    con = future.get(5, TimeUnit.SECONDS); 
} catch (InterruptedException | ExecutionException | TimeoutException ex) { 
    Logger.getLogger(Scratch.class.getName()).log(Level.SEVERE, null, ex); 
} 
executor.shutdownNow(); 

if (con == null) { 
    System.out.println("Could not establish connection"); 
} else { 
    System.out.println("Connection established!"); 
} 
Problemi correlati