Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

ResultSetImpl.checkColumnBounds या ResultSetImpl.getStringInternal में समसामयिक NullPointerException

इस प्रश्न को पोस्ट किए हुए काफी समय हो गया है, और मैं एक उत्तर पोस्ट करना चाहता हूं जो सटीक परिदृश्य का वर्णन करता है जिसके कारण यह मुश्किल NullPointerException हुआ। ।

मुझे लगता है कि यह भविष्य के पाठकों की मदद कर सकता है जो इस तरह के भ्रमित अपवाद का सामना करते हैं, बॉक्स के बाहर सोचते हैं, क्योंकि मेरे पास संदेह करने का लगभग हर कारण था कि यह एक MySQL कनेक्टर बग था, भले ही यह बिल्कुल नहीं था।

इस अपवाद की जांच करते समय मुझे यकीन था कि मेरा एप्लिकेशन संभवतः डीबी कनेक्शन को बंद नहीं कर सकता है, जबकि इससे डेटा पढ़ने की कोशिश कर रहा है, क्योंकि मेरे डीबी कनेक्शन थ्रेड में साझा नहीं किए जाते हैं, और यदि एक ही थ्रेड ने कनेक्शन बंद कर दिया और फिर एक्सेस करने का प्रयास किया यह, एक अलग अपवाद फेंका जाना चाहिए था (कुछ SQLException ) यही मुख्य कारण था कि मुझे mysql कनेक्टर बग पर संदेह हुआ।

यह पता चला कि एक ही कनेक्शन को एक्सेस करने वाले दो थ्रेड थे आख़िरकार। इसका पता लगाना कठिन था क्योंकि इनमें से एक धागा कचरा संग्रहकर्ता धागा था

मेरे द्वारा पोस्ट किए गए कोड पर वापस जा रहे हैं:

Connection conn = ... // the connection is open
...
for (String someID : someIDs) {
    SomeClass sc = null;
    PreparedStatement
        stmt = conn.prepareStatement ("SELECT A, B, C, D, E, F, G, H FROM T WHERE A = ?");
    stmt.setString (1, "someID");
    ResultSet res = stmt.executeQuery ();
    if (res.next ()) {
        sc = new SomeClass ();
        sc.setA (res.getString (1));
        sc.setB (res.getString (2));
        sc.setC (res.getString (3));
        sc.setD (res.getString (4));
        sc.setE (res.getString (5));
        sc.setF (res.getInt (6));
        sc.setG (res.getString (7));
        sc.setH (res.getByte (8)); // the exception is thrown here
    }
    stmt.close ();
    conn.commit ();
    if (sc != null) {
        // do some processing that involves loading other records from the
        // DB using the same connection
    }
}
conn.close();

समस्या "कुछ प्रसंस्करण करें जिसमें एक ही कनेक्शन का उपयोग कर डीबी से अन्य रिकॉर्ड लोड करना शामिल है" खंड में निहित है, दुर्भाग्य से, मैंने अपने मूल प्रश्न में शामिल नहीं किया, क्योंकि मुझे नहीं लगता था कि समस्या वहां थी।

उस अनुभाग में ज़ूम करते हुए, हमारे पास है:

if (sc != null) {
    ...
    someMethod (conn);
    ...
}

और someMethod ऐसा दिखता है:

public void someMethod (Connection conn) 
{
    ...
    SomeOtherClass instance = new SomeOtherClass (conn);
    ...
}

SomeOtherClass इस तरह दिखता है (बेशक मैं यहाँ सरल कर रहा हूँ):

public class SomeOtherClass
{
    Connection conn;

    public SomeOtherClass (Connection conn) 
    {
        this.conn = conn;
    }

    protected void finalize() throws Throwable
    { 
        if (this.conn != null)
            conn.close();
    }

}

SomeOtherClass कुछ परिदृश्यों में अपना स्वयं का DB कनेक्शन बना सकता है, लेकिन अन्य परिदृश्यों में मौजूदा कनेक्शन को स्वीकार कर सकता है, जैसे कि हमारे यहाँ है।

जैसा कि आप देख सकते हैं, उस अनुभाग में someMethod . के लिए एक कॉल है जो खुले कनेक्शन को तर्क के रूप में स्वीकार करता है। someMethod SomeOtherClass . के स्थानीय उदाहरण से कनेक्शन पास करता है . SomeOtherClass एक finalize . था विधि जो कनेक्शन को बंद कर देती है।

अब, someMethod . के बाद रिटर्न, instance कचरा संग्रहण के लिए पात्र हो जाता है। जब यह कचरा एकत्र किया जाता है, तो इसे finalize मेथड को गारबेज कलेक्टर थ्रेड द्वारा कॉल किया जाता है, जो कनेक्शन को बंद कर देता है।

अब हम लूप के लिए वापस आते हैं, जो उसी कनेक्शन का उपयोग करके SELECT स्टेटमेंट को निष्पादित करना जारी रखता है जिसे कचरा कलेक्टर थ्रेड द्वारा किसी भी समय बंद किया जा सकता है।

यदि गारबेज कलेक्टर थ्रेड कनेक्शन को बंद करने के लिए होता है, जबकि एप्लिकेशन थ्रेड कुछ mysql कनेक्टर विधि के बीच में होता है जो खुले होने वाले कनेक्शन पर निर्भर करता है, एक NullPointerException हो सकता है।

finalize को हटा रहा है विधि ने समस्या का समाधान किया।

हम अक्सर finalize को ओवरराइड नहीं करते हैं हमारी कक्षाओं में विधि, जिससे बग का पता लगाना बहुत मुश्किल हो गया।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. दिनांक mysql में 0000-00-00 00:00:00 के रूप में सम्मिलित हो रहा है

  2. PHP फॉर्म mySQL डेटाबेस में सम्मिलित नहीं हो रहा है

  3. विशिष्ट डेटाबेस से सभी तालिका नाम, स्तंभ नाम और स्तंभ मान पुनर्प्राप्त करें

  4. एसक्यूएल - जहां जॉइन के साथ क्लॉज

  5. MySQL सम्मिलित क्वेरी से नया रिकॉर्ड प्राथमिक कुंजी आईडी प्राप्त करें?