हमने इस मुद्दे के कारण का पता लगा लिया है। यह नवीनतम JDBC ड्राइवरों 9.2-100x में setQueryTimeout() के बग्गी कार्यान्वयन द्वारा समझाया गया है। यदि आप मैन्युअल रूप से कनेक्शन खोलते / बंद करते हैं तो ऐसा नहीं हो सकता है, लेकिन अक्सर कनेक्शन पूलिंग के साथ होता है और autocommit गलत . पर सेट करें . इस मामले में, setQueryTimeout() को गैर-शून्य मान के साथ कॉल किया जाना चाहिए (उदाहरण के लिए, स्प्रिंग फ्रेमवर्क @Transactional(timeout =xxx) एनोटेशन का उपयोग करके)।
यह पता चला है, जब भी कथन निष्पादन के दौरान SQL अपवाद उठाया जाता है, रद्दीकरण टाइमर रद्द नहीं किया गया है और जीवित रहता है (इस तरह इसे कार्यान्वित किया जाता है)। पूलिंग के कारण, पीछे का कनेक्शन बंद नहीं होता है, लेकिन पूल में वापस आ जाता है। बाद में, जब रद्दीकरण टाइमर ट्रिगर होता है, तो यह उस कनेक्शन से जुड़ी क्वेरी को बेतरतीब ढंग से रद्द कर देता है जिसके साथ इस टाइमर को बनाया गया है। इस समय, यह एक पूरी तरह से अलग क्वेरी है जो यादृच्छिकता प्रभाव की व्याख्या करती है।
सुझाया गया समाधान setQueryTimeout() को छोड़ देना है और इसके बजाय PostgreSQL कॉन्फ़िगरेशन (statement_timeout) का उपयोग करना है। यह समान स्तर का लचीलापन प्रदान नहीं करता है लेकिन कम से कम हमेशा काम करता है।