2013-02-15 57 views
5

मैं जावा अनुप्रयोग के साथ किसी समस्या का निवारण करने का प्रयास कर रहा हूं जो कि MySQL डेटाबेस से कनेक्ट करने के लिए जेडीबीसी का उपयोग कर रहा है। सतह मुद्दा यह है कि जब एक वैध डेटाबेस से कनेक्ट होता है, DriverManager.getConnection कभी-कभी NULL लौटाएगा, जबकि कुछ ही मिनट बाद यह सटीक उसी डेटाबेस के लिए एक वैध कनेक्शन लौटाएगा।जावा/जेडीबीसी/MySQL: मैं समस्या निवारण कैसे करूं DriverManager.getConnection() वापस लौट रहा है?

मैं इस समस्या का निवारण करने की कोशिश करने की स्थिति में हूं, लेकिन जावा, जेडीबीसी, और MySQL बैठक की मेरी समझ काफी सीमित है। मैं इस पर बहुत सारे शोध कर रहा हूं, लेकिन एक दीवार मारा है और यह नहीं पता कि यहां से कहाँ जाना है।

यहाँ मैं अब तक क्या किया है है:

  • जावा छोर पर, मैं कोड DriverManager.getConnection सभी तरह का पता लगाया है()। मैंने यह निर्धारित किया है कि वहां से पूरा कनेक्शन आ रहा है, लेकिन मेरे पास कोई कनेक्शन नहीं है जो getConnection के हुड के नीचे चल रहा है। मैं इस ऑनलाइन की पूरी तरह से व्याख्या करने के लिए संघर्ष कर रहा हूं।
  • MySQL अंत में, मैंने सत्यापित किया है कि मेरे पास बहुत से कनेक्शन उपलब्ध हैं (कई बार लगभग 1000 मुफ्त कनेक्शन), इसलिए मुझे पता है कि मैं वहां अधिकतम कनेक्शन से अधिक नहीं हूं। लॉग देखकर, मैं यह निर्धारित करने में सक्षम था कि समय-फ्रेम के दौरान कनेक्शन की थोड़ी अधिक संख्या में निरस्त किया जा रहा है, जहां मुझे सबसे अधिक समस्याएं हैं, लेकिन मुझे नहीं पता कि इन कनेक्शनों को निरस्त क्यों किया गया था (MySQL abort, जेडीबीसी, जावा अनुप्रयोग?) मुझे यकीन नहीं है कि अगर कुछ और है तो मुझे MySQL अंत की तलाश करने की आवश्यकता है।
  • मध्य में, जेडीबीसी के साथ, मैं बहुत खो गया हूं। मैं http://dev.mysql.com/doc/refman/5.1/en/connector-j.html पर MySQL कनेक्टर/जे पर पढ़ रहा हूं, लेकिन यह निश्चित नहीं है कि वह जानकारी जावा द्वारा उपयोग किए जा रहे जेडीबीसी ड्राइवर से संबंधित है।

कोई भी दिशा जहां से मैं यहां से जा सकता हूं, की सराहना की जाएगी।

धन्यवाद!

संपादित करें - 2/15, 10:35 पूर्वाह्न सीएसटी मैं अधिक विशिष्ट नहीं होने के लिए क्षमा चाहता हूं। यह एप्लिकेशन एक उत्पादन अनुप्रयोग है जो आम तौर पर ठीक काम करता है। यह बिना किसी समस्या के दिन हजारों कनेक्शन सफलतापूर्वक संसाधित कर रहा है, यह सिर्फ यह मुद्दा दिन के दौरान यादृच्छिक समय पर उगाएगा, और ऐसा होने पर 30 सेकंड से 5 मिनट तक कहीं भी जारी रहेगा। getConnection बीच में कहीं

var dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.jdbc.Driver','jdbc:mysql://'+ serverName +':' + port + '/' + database, userName, password); 

public static DatabaseConnection createDatabaseConnection(String driver, String address, String username, String password) throws SQLException { 
     try { 
      Class.forName(driver); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     Properties info = new Properties(); 
     info.setProperty("user", username); 
     info.setProperty("password", password); 

     // this property should only be set if it's for embedded database 
     info.setProperty("shutdown", "true"); 

     return new DatabaseConnection(address, info); 
    } 

public DatabaseConnection(String address, Properties info) throws SQLException { 
     logger.debug("creating new database connection: address=" + address + ", " + info); 
     this.address = address; 
     connection = DriverManager.getConnection(address, info); 
    } 

मैं नहीं मानता कि वहाँ वास्तव में कोड के साथ किसी भी समस्या नहीं है, बल्कि एक मुद्दा:

यहाँ कोड है कि मैं DriverManager.getConnection करने के लिए नीचे सभी तरह से पता लगाया गया है() और MySQL।

+1

कुछ कोड पोस्ट करें और यह आपकी मदद करना आसान होगा। – duffymo

+0

ऐसा लगता है कि कनेक्शन (नेटवर्क) अविश्वसनीय है और आपकी मशीन हमेशा मशीन से कनेक्ट नहीं होती है, इसलिए कभी-कभी कनेक्शन स्थापित नहीं किया जा सकता है –

+0

जेफ - यह मेरा संदेह है, लेकिन यह कहना मुश्किल है जहां यह हो सकता है। यदि मेरे लिए विभिन्न कारणों का निर्धारण करने का कोई तरीका है, तो DriverManager.getConnection NULL क्यों वापस आ जाएगा, जो मुझे इस मुद्दे को महत्वपूर्ण रूप से ट्रैक करने में सहायता करेगा। – TACHEON

उत्तर

7

एक व्यक्ति चालक एक कनेक्ट अनुरोध के लिए अशक्त लौट सकते हैं, JDBC 4.1 विनिर्देश इस कहते हैं:

जब DriverManager एक कनेक्शन स्थापित करने की कोशिश कर रहा है, यह चालक की कनेक्ट विधि को कॉल करता है और ड्राइवर को यूआरएल पास करता है। यदि चालक कार्यान्वयन यूआरएल को समझता है, तो यह एक कनेक्शन ऑब्जेक्ट लौटाएगा या एक एसक्यूएलएक्सप्शन फेंक देगा यदि कनेक्शन को डेटाबेस में मैड नहीं किया जा सकता है। यदि चालक कार्यान्वयन URL को समझ में नहीं आता है, तो यह शून्य हो जाएगा।

हालांकि, java.sql.DriverManager के कोड को देखकर (जावा 7 अद्यतन 13 में), यह हमेशा एक SQLException संदेश कोई उपयुक्त ड्राइवर < यूआरएल > के लिए मिला के साथ फेंक होगा जब सभी उपलब्ध चालकों के लिए null वापस आ गए एक connect(url, properties) कॉल:

// Worker method called by the public getConnection() methods. 
private static Connection getConnection(
    String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { 
// Removed some classloading stuff for brevity 
    if(url == null) { 
     throw new SQLException("The url cannot be null", "08001"); 
    } 
    // Walk through the loaded registeredDrivers attempting to make a connection. 
    // Remember the first exception that gets raised so we can reraise it. 
    SQLException reason = null; 
    for(DriverInfo aDriver : registeredDrivers) { 
     // If the caller does not have permission to load the driver then 
     // skip it. 
     if(isDriverAllowed(aDriver.driver, callerCL)) { 
      try { 
       println(" trying " + aDriver.driver.getClass().getName()); 
       Connection con = aDriver.driver.connect(url, info); 
       if (con != null) { 
        // Success! 
        println("getConnection returning " + aDriver.driver.getClass().getName()); 
        return (con); 
       } 
      } catch (SQLException ex) { 
       if (reason == null) { 
        reason = ex; 
       } 
      } 
     } else { 
      println(" skipping: " + aDriver.getClass().getName()); 
     } 
    } 
    // if we got here nobody could connect. 
    if (reason != null) { 
     println("getConnection failed: " + reason); 
     throw reason; 
    } 
    println("getConnection: no suitable driver found for "+ url); 
    throw new SQLException("No suitable driver found for "+ url, "08001"); 
} 

दूसरे शब्दों में: क्या आप का वर्णन नहीं हो सकता (कम से कम जावा 7 अद्यतन 13 में नहीं)। जावा 5 अपडेट 22 स्रोतों पर एक त्वरित झलक दिखाता है कि लगभग समान कार्यान्वयन यह आसानी से वापस नहीं आ सकता है।

अधिक संभावना है कि आप एक अपवाद निगल रहे हैं और फिर Connection वेरिएबल या फ़ील्ड का उपयोग करने का प्रयास कर रहे हैं जिसमें मूल्य शून्य है।

एक और संभावना यह होगा कि आप DriverManager.getConnection(url, ...) के सिलसिले प्राप्त नहीं कर रहे हैं, लेकिन DriverManager.getDriver(url).connect(...) साथ क्योंकि ऊपर स्थापित नियमों का null लौट सकते हैं जो। यदि आप ऐसा करते हैं, तो यह संभवतः कनेक्टर/जे चालक में एक बग को इंगित करता है यदि आप हमेशा एक ही यूआरएल का उपयोग कर रहे हैं: एक ड्राइवर एक बिंदु पर तय नहीं कर सकता है कि वह एक विशिष्ट यूआरएल के लिए कनेक्शन लौटाए और अगली वापसी नल हो। यह हमेशा एक ही यूआरएल के लिए Connection या SQLException फेंकना चाहिए।

+2

यह स्पष्ट करने के लिए धन्यवाद कि यह कभी भी वापस नहीं लौटाएगा, बल्कि इसके बजाय एक अपवाद। मैंने कुछ और खुदाई की और पाया कि अपवाद को निगल लिया जा रहा है। मैं कई बार कोड पर गया हूं, मुझे यकीन नहीं है कि मुझे यह कैसे याद आया। – TACHEON

+0

खुशी है कि मैं मदद कर सकता हूँ! –

2

हां, DriverManager वह कक्षा है जो आपके लिए कनेक्शन प्राप्त करती है।

यह जेएसबीसी ड्राइवर वर्गों का उपयोग करके प्रबंधित करता है जो आपको MySQL कनेक्टर-जे जेएआर के साथ मिलता है। जब आप शुरू करते हैं तो उस जेएआर को आपके CLASSPATH में होना चाहिए।

यह सुनिश्चित करके प्रारंभ करें कि आप मशीन से MySQL से कनेक्ट कर सकते हैं जहां आप जावा ऐप चलाते हैं। MySQL व्यवस्थापक ऐप में सफलतापूर्वक लॉग इन करें और आपको पहली बाधा से पहले मिल गया है।

मैं आपको अपनी स्थिति के लिए डॉक्टर के लिए एक कक्षा की पेशकश करूंगा। विधियां आम तौर पर आपके लिए उपयोगी हो सकती हैं।अपनी स्थिति के लिए कनेक्शन, क्रेडेंशियल और क्वेरी संशोधित करें और इसे आज़माएं। I पता यह कोड काम करता है।

package persistence; 

import java.sql.*; 
import java.util.*; 

/** 
* util.DatabaseUtils 
* User: Michael 
* Date: Aug 17, 2010 
* Time: 7:58:02 PM 
*/ 
public class DatabaseUtils { 
/* 
    private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver"; 
    private static final String DEFAULT_URL = "jdbc:oracle:thin:@host:1521:database"; 
    private static final String DEFAULT_USERNAME = "username"; 
    private static final String DEFAULT_PASSWORD = "password"; 
*/ 
/* 
    private static final String DEFAULT_DRIVER = "org.postgresql.Driver"; 
    private static final String DEFAULT_URL = "jdbc:postgresql://localhost:5432/party"; 
    private static final String DEFAULT_USERNAME = "pgsuper"; 
    private static final String DEFAULT_PASSWORD = "pgsuper"; 
*/ 
    private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver"; 
    private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/party"; 
    private static final String DEFAULT_USERNAME = "party"; 
    private static final String DEFAULT_PASSWORD = "party"; 

    public static void main(String[] args) { 
     long begTime = System.currentTimeMillis(); 

     String driver = ((args.length > 0) ? args[0] : DEFAULT_DRIVER); 
     String url = ((args.length > 1) ? args[1] : DEFAULT_URL); 
     String username = ((args.length > 2) ? args[2] : DEFAULT_USERNAME); 
     String password = ((args.length > 3) ? args[3] : DEFAULT_PASSWORD); 

     Connection connection = null; 

     try { 
      connection = createConnection(driver, url, username, password); 
      DatabaseMetaData meta = connection.getMetaData(); 
      System.out.println(meta.getDatabaseProductName()); 
      System.out.println(meta.getDatabaseProductVersion()); 

      String sqlQuery = "SELECT PERSON_ID, FIRST_NAME, LAST_NAME FROM PERSON ORDER BY LAST_NAME"; 
      System.out.println("before insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST)); 

      connection.setAutoCommit(false); 
      String sqlUpdate = "INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES(?,?)"; 
      List parameters = Arrays.asList("Foo", "Bar"); 
      int numRowsUpdated = update(connection, sqlUpdate, parameters); 
      connection.commit(); 

      System.out.println("# rows inserted: " + numRowsUpdated); 
      System.out.println("after insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST)); 
     } catch (Exception e) { 
      rollback(connection); 
      e.printStackTrace(); 
     } finally { 
      close(connection); 
      long endTime = System.currentTimeMillis(); 
      System.out.println("wall time: " + (endTime - begTime) + " ms"); 
     } 
    } 

    public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException { 
     Class.forName(driver); 
     if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0)) { 
      return DriverManager.getConnection(url); 
     } else { 
      return DriverManager.getConnection(url, username, password); 
     } 
    } 

    public static void close(Connection connection) { 
     try { 
      if (connection != null) { 
       connection.close(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 


    public static void close(Statement st) { 
     try { 
      if (st != null) { 
       st.close(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void close(ResultSet rs) { 
     try { 
      if (rs != null) { 
       rs.close(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void rollback(Connection connection) { 
     try { 
      if (connection != null) { 
       connection.rollback(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static List<Map<String, Object>> map(ResultSet rs) throws SQLException { 
     List<Map<String, Object>> results = new ArrayList<Map<String, Object>>(); 
     try { 
      if (rs != null) { 
       ResultSetMetaData meta = rs.getMetaData(); 
       int numColumns = meta.getColumnCount(); 
       while (rs.next()) { 
        Map<String, Object> row = new HashMap<String, Object>(); 
        for (int i = 1; i <= numColumns; ++i) { 
         String name = meta.getColumnName(i); 
         Object value = rs.getObject(i); 
         row.put(name, value); 
        } 
        results.add(row); 
       } 
      } 
     } finally { 
      close(rs); 
     } 
     return results; 
    } 

    public static List<Map<String, Object>> query(Connection connection, String sql, List<Object> parameters) throws SQLException { 
     List<Map<String, Object>> results = null; 
     PreparedStatement ps = null; 
     ResultSet rs = null; 
     try { 
      ps = connection.prepareStatement(sql); 

      int i = 0; 
      for (Object parameter : parameters) { 
       ps.setObject(++i, parameter); 
      } 
      rs = ps.executeQuery(); 
      results = map(rs); 
     } finally { 
      close(rs); 
      close(ps); 
     } 
     return results; 
    } 

    public static int update(Connection connection, String sql, List<Object> parameters) throws SQLException { 
     int numRowsUpdated = 0; 
     PreparedStatement ps = null; 
     try { 
      ps = connection.prepareStatement(sql); 

      int i = 0; 
      for (Object parameter : parameters) { 
       ps.setObject(++i, parameter); 
      } 
      numRowsUpdated = ps.executeUpdate(); 
     } finally { 
      close(ps); 
     } 
     return numRowsUpdated; 
    } 
} 

संकलन के बाद, इस आदेश के साथ इसे चलाने:

java -classpath .;<Connector-J driver path here> persistence.DatabaseUtils