5

हमारे पास एक ऐप है जो कनेक्शन लीक लगता है (SQL सर्वर का कहना है कि अधिकतम पूल आकार तक पहुंच गया है)। मैं अपनी देव मशीन (जाहिर है) पर अकेला हूं, और बस ऐप नेविगेट करके, मैं इस त्रुटि को ट्रिगर करता हूं। SQL सर्वर गतिविधि मॉनिटर मेरे डेटाबेस का उपयोग कर प्रक्रियाओं की एक बड़ी संख्या दिखाता है।ट्रैक कनेक्शन लीक

मैं यह जानना चाहता हूं कि कौन सी फाइलें खुले कनेक्शन हैं लेकिन इसका उपयोग न करें। मैं प्रत्येक फ़ाइल के लिए grep जैसे कुछ का उपयोग करने के बारे में सोच रहा था, "ओपेन()" की संख्या और ".Close()" की संख्या गिनती है, और फ़ाइल प्राप्त करें जिसके लिए संख्या बराबर नहीं है। क्या यह यथार्थवादी है?

बोनस प्रश्न: क्या SQL सर्वर गतिविधि मॉनीटर में मिली प्रक्रियाएं कनेक्शन से मेल खाते हैं? यदि नहीं, तो मैं कैसे पता लगा सकता हूं कि मेरे डेटाबेस पर कितने कनेक्शन खुले हैं?

ऐप एसक्यूएल सर्वर 2005 के साथ एएसपीनेट (vb) 3.5 में है। वर्तमान में हम linq (अभी तक) या ऐसा कुछ भी उपयोग नहीं करते हैं।

धन्यवाद

+0

आपकी एप्लिकेशन किस भाषा में कोडित है? –

+0

Asp.net। मैंने इसे प्रतिबिंबित करने के लिए मूल प्रश्न संपादित किया है। – thomasb

उत्तर

9

जब एसक्यूएल सर्वर साइड आप एक दृश्य है, जिस पर प्रश्नों सो कनेक्शन पर पिछले रन हैं पाने के लिए निम्न क्वेरी चला सकते हैं से कोड को देखकर। आवेदन की ओर से (खुले कनेक्शनों कुछ नहीं कर रहे हैं जो)

SELECT ec.session_id, last_read, last_write, text, client_net_address, program_name, host_process_id, login_name 
FROM sys.dm_exec_connections ec 
JOIN sys.dm_exec_sessions es 
    ON ec.session_id = es.session_id 
CROSS APPLY sys.dm_exec_sql_text(ec.most_recent_sql_handle) AS dest 
where es.status = 'sleeping' 

आप sos.dll साथ डीबग कर सकते हैं निम्न लेख में वर्णित हैं:

यदि आपको विंडबग का उपयोग करने के तरीके के बारे में अधिक जानकारी चाहिए, तो ये लेख एक अच्छे परिचय हैं:

+0

धन्यवाद, लेकिन आपका भाग 2 लिंक भाग 1 के समान है। भाग 2 यहां है: http://blogs.msdn.com/b/psssql/archive/2009/02/10/how-to-troubleshoot-leaked- sqlconnection-objects-net-2-0-part-2.aspx – thomasb

+0

मुझे लगता है कि मुझे उन लेखों में कुछ भी समझ में नहीं आता है।मुझे यह भी समझ में नहीं आता कि आदेश कहां टाइप करें। – thomasb

+0

क्षमा करें, दूसरे भाग के लिंक को ठीक करें। लेख आपके आवेदन को डीबग करने के लिए windbg.exe और sos.dll का उपयोग करने के बारे में हैं। –

1

tackle connection leaks is to do it during testing का सबसे अच्छा तरीका।

आप एक स्वचालित उपयोगिता का उपयोग कर सकते हैं ताकि प्रत्येक परीक्षण सत्यापित करता है कि कनेक्शन रिसाव है या नहीं।

@BeforeClass 
public static void initConnectionLeakUtility() { 
    if (enableConnectionLeakDetection) { 
     connectionLeakUtil = new ConnectionLeakUtil(); 
    } 
} 

@AfterClass 
public static void assertNoLeaks() { 
    if (enableConnectionLeakDetection) { 
     connectionLeakUtil.assertNoLeaks(); 
    } 
} 

ConnectionLeakUtil इस तरह दिखता है:

public class ConnectionLeakUtil { 

    private JdbcProperties jdbcProperties = JdbcProperties.INSTANCE; 

    private List idleConnectionCounters = 
     Arrays.asList(
      H2IdleConnectionCounter.INSTANCE, 
      OracleIdleConnectionCounter.INSTANCE, 
      PostgreSQLIdleConnectionCounter.INSTANCE, 
      MySQLIdleConnectionCounter.INSTANCE 
    ); 

    private IdleConnectionCounter connectionCounter; 

    private int connectionLeakCount; 

    public ConnectionLeakUtil() { 
     for (IdleConnectionCounter connectionCounter : 
      idleConnectionCounters) { 
      if (connectionCounter.appliesTo( 
       Dialect.getDialect().getClass())) { 
       this.connectionCounter = connectionCounter; 
       break; 
      } 
     } 
     if (connectionCounter != null) { 
      connectionLeakCount = countConnectionLeaks(); 
     } 
    } 

    public void assertNoLeaks() { 
     if (connectionCounter != null) { 
      int currentConnectionLeakCount = countConnectionLeaks(); 
      int diff = currentConnectionLeakCount - connectionLeakCount; 
      if (diff > 0) { 
       throw new ConnectionLeakException( 
        String.format(
         "%d connection(s) have been leaked! Previous leak count: %d, Current leak count: %d", 
         diff, 
         connectionLeakCount, 
         currentConnectionLeakCount 
        ) 
       ); 
      } 
     } 
    } 

    private int countConnectionLeaks() { 
     try (Connection connection = newConnection()) { 
      return connectionCounter.count(connection); 
     } 
     catch (SQLException e) { 
      throw new IllegalStateException(e); 
     } 
    } 

    private Connection newConnection() { 
     try { 
      return DriverManager.getConnection(
       jdbcProperties.getUrl(), 
       jdbcProperties.getUser(), 
       jdbcProperties.getPassword() 
      ); 
     } 
     catch (SQLException e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

IdleConnectionCounter कार्यान्वयन इस blog post में पाया जा सकता है, और इस तरह MySQL संस्करण:

public class MySQLIdleConnectionCounter implements IdleConnectionCounter { 

    public static final IdleConnectionCounter INSTANCE = 
     new MySQLIdleConnectionCounter(); 

    @Override 
    public boolean appliesTo(Class<? extends Dialect> dialect) { 
     return MySQL5Dialect.class.isAssignableFrom(dialect); 
    } 

    @Override 
    public int count(Connection connection) { 
     try (Statement statement = connection.createStatement()) { 
      try (ResultSet resultSet = statement.executeQuery(
        "SHOW PROCESSLIST")) { 
       int count = 0; 
       while (resultSet.next()) { 
        String state = resultSet.getString("command"); 
        if ("sleep".equalsIgnoreCase(state)) { 
         count++; 
        } 
       } 
       return count; 
      } 
     } 
     catch (SQLException e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

अब, जब आप चलाने के लिए अपनी परीक्षण, एक कनेक्शन लीक होने पर आपको विफलता मिल जाएगी:

:hibernate-core:test 

org.hibernate.jpa.test.EntityManagerFactoryClosedTest > classMethod FAILED 
    org.hibernate.testing.jdbc.leak.ConnectionLeakException