ConnectionPool.java
ऐसा लगता है कि आप इस कोड स्निपेट को borrowConnection()
. में हिट कर रहे हैं विधि:
//we didn't get a connection, lets see if we timed out
if (con == null) {
if ((System.currentTimeMillis() - now) >= maxWait) {
throw new SQLException("[" + Thread.currentThread().getName()+"] " +
"Timeout: Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +
" seconds, none available["+busy.size()+" in use].");
} else {
//no timeout, lets try again
continue;
}
}
तो इस हिसाब से आपका कनेक्शन शून्य है .
con
. का मान लाइन पर पुनः प्राप्त किया जाता है:
PooledConnection con = idle.poll();
यदि आप कोड को ट्रैक करते हैं, तो आपको idle
दिखाई देगा है (आपके कॉन्फ़िगरेशन के आधार पर, लेकिन डिफ़ॉल्ट रूप से) FairBlockingQueue
. आप संकेतों के लिए कार्यान्वयन की जांच कर सकते हैं।
सामान्य तौर पर आपको हमेशा रिजल्टसेट, स्टेटमेंट और कनेक्शन को बंद करना होता है और उपयोग किए गए कनेक्शन को सही ढंग से पूल में वापस छोड़ दिया जाना चाहिए। ऐसा सही तरीके से नहीं करने के परिणामस्वरूप कनेक्शन कभी बंद नहीं हो सकते => पुन:उपयोग के लिए फिर कभी उपलब्ध नहीं होना (कनेक्शन पूल "लीक" )।
मेरा सुझाव है कि आप पूल की स्थिति पर कुछ विस्तृत लॉगिंग का निर्माण करें और समस्या को अलग करने के लिए इसकी निगरानी करें।
डेटाबेस कनेक्शन पूल लीक को रोकने के लिए अपाचे से कुछ दिशानिर्देश:
removeAbandoned="true"
छोड़े गए डेटाबेस कनेक्शन हटा दिए जाते हैं और पुनर्नवीनीकरण किए जाते हैं
removeAbandonedTimeout="60"
एक डेटाबेस कनेक्शन को छोड़े जाने से पहले निष्क्रिय होने के सेकंड की संख्या निर्धारित करें
logAbandoned="true"
कोड का एक स्टैक ट्रेस लॉग करें जिसने डेटाबेस कनेक्शन संसाधनों को छोड़ दिया। ध्यान रखें कि "छोड़े गए कनेक्शनों का लॉगिंग प्रत्येक कनेक्शन उधार के लिए ओवरहेड जोड़ता है क्योंकि एक स्टैक ट्रेस उत्पन्न करना होता है।"
मुझे अब भी लगता है कि maxWait
को थोड़ा बढ़ा दिया जाए value (1200, 1500, 1700 - बस प्रयोग करें, उपयोगकर्ता के दृष्टिकोण से प्रतिक्रिया समय में कोई अंतर नहीं होगा) उन दुर्लभ मामलों को साफ़ कर देगा, जिनमें आपको अभी भी समस्याएँ हैं।