2009-11-05 3 views
21

Je suis en train de se connecter à DB en utilisant la méthode standard JDBCdélai de connexion pour DriverManager getConnection

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

Y at-il une valeur maximale de délai d'attente sur la connexion, combien de temps dure une connexion en direct, puis-je augmenter la valeur . Je veux que la connexion soit ouverte pour toujours, est-ce une bonne idée?

Répondre

24

La valeur est généralement contrôlée par DB. Vous n'avez aucun contrôle sur le code. Cela dépend du serveur de base de données utilisé. Il est habituellement d'environ 30 minutes jusqu'à une heure. D'autre part, garder un Connection ouvert pour toujours est une très mauvaise idée. La meilleure pratique consiste à acquérir et près Connection, Statement et ResultSet dans le champ possiblele plus court pour éviter les fuites de ressources et les accidents d'application potentiels causés par les fuites et les délais d'attente.

Vrai, la connexion du DB est une tâche coûteuse. Si votre application est supposée fonctionner relativement longtemps et que vous devez connecter la base de données assez souvent, pensez à utiliser un pool de connexions pour améliorer les performances de connexion. Si votre application est une application Web, jetez un coup d'oeil dans la documentation du serveur d'applications, elle fournit généralement une fonction de mise en commun de connexions dans un DataSource. S'il s'agit d'une application cliente, recherchez des bibliothèques de pool de connexion tierces qui ont prouvé leur robustesse avec les années, telles que Apache Commons DBCP (couramment utilisé dans les serveurs d'applications de lot), C3P0 (connu de Hibernate) et Proxool (si vous voulez des connexions XA). N'oubliez pas que lorsque vous utilisez un pool de connexions, vous devez toujours écrire le code JDBC approprié, i.o.w. acquérir et fermer toutes les ressources dans la portée la plus courte possible. À son tour, le pool de connexion s'inquiète de la fermeture de la connexion ou de la relâcher dans le pool pour une réutilisation ultérieure.

Vous pouvez obtenir plus d'informations sur this article comment faire les bases de JDBC de la bonne façon.

Espérons que cela aide et le codage heureux.

+2

DBCP est un horrible, * horrible * pool de connexion.Ne l'utilisez jamais – erickson

+0

Intéressant.J'ai jamais eu de sérieux problèmes avec lui lorsqu'il est utilisé dans la saveur d'une source de données gérée Tomcat 6.0.Essayez d'élaborer? – BalusC

+6

Eh bien, vous vouloir utiliser un pool lorsque les ressources sont "chères" (prendre le temps de créer) DBCP (ou vraiment le pool sous-jacent) détient un verrou sur l'ensemble du pool pendant que de nouveaux objets sont produits.Ceci empêche les threads qui ont fini avec une ressource Pendant ce temps, d'autres threads sont bloqués en essayant d'obtenir ces ressources, car ces acquisitions de verrous n'utilisent pas le paquet concurrent, elles ne sont pas interruptibles, ce qui nuit à la performance dans des conditions normales. En fait, avec la DB, ça devient * vraiment * moche, vraiment rapide – erickson

24

Vous pouvez régler le délai d'attente sur le DriverManager comme ceci:

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

Ce qui impliquerait que si la connexion ne peut pas ouvrir dans le délai étant donné qu'il arrive à expiration.

En termes de maintien d'une connexion ouverte pour toujours, il est possible que vous ne fermiez pas la connexion, mais ce n'est peut-être pas une bonne idée. Les connexions doivent être fermées dès que vous en avez fini avec elles.

Si vous souhaitez optimiser l'ouverture et la fermeture des connexions, vous pouvez utiliser un pool de connexions.

+3

Hmm, IIRC définit uniquement le délai d'attente pendant lequel DriverManager doit attendre avant que la base de données ne renvoie une connexion. Il ne définit pas le délai d'attente de la connexion. Voir aussi: http://java.sun.com/javase/6/docs/api/java/sql/DriverManager.html#setLoginTimeout%28int%29 – BalusC

+1

Cest juste @BalusC. Comme je l'ai mentionné, ce délai d'attente est seulement combien de temps le DriverManager attend une connexion et non combien de temps la connexion reste ouverte. –

+2

Je dois cependant admettre (et vous aussi probablement) que c'est la bonne réponse à la question telle que formulée littéralement dans le sujet du sujet. Mais la question réelle dans le message de sujet s'est avérée être quelque chose de différent. – BalusC

5

Voici comment le faire avec chauffeur connecteur/J MYSQL:

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

Il a travaillé pour moi après setLoginTimeout() n'a rien fait.

+4

c'est faux 'connectTimeout = TIME_IN_MILLIS' car c'est' connectTimeout = TIME_IN_SECONDS' plus d'infos ici http://dev.mysql.com/doc/refman/5.1/fr/mysql-command-options.html#option_mysql_connect_timeout – HCarrasko

0

Vous pouvez utiliser l'interface ExecutorService à partir de Java. Voici un exemple de ce que vous devez faire.

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

Une idée terrible . Cela crée une ThreadFactory, un Thread, exécute connect en parallèle et implémente un timeout dans 'get()', tout en laissant la connexion proprement dite se poursuivre sans véritable moyen de s'annuler. – EJP

4

Juste reposter une republication plus complète d'un commentaire de flamming_python utilisateur comme réponse parce qu'il a fonctionné pour moi:

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

Original Commentaire:
« LoL @ vos fils - vous pouvez le faire tout à fait simplement en créant un objet prop Properties, puis prop.put ("connectTimeout", "2000") (où le "2000" est le délai en ms), puis passez votre objet prop à la méthode DriverManager.getConnection() avec votre url "

0

A s bestro suggéré, il est possible d'utiliser un futur avec un timeout associé. Par exemple:

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!"); 
}