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
स्रोत
2016-07-12 13:10:58
आपकी एप्लिकेशन किस भाषा में कोडित है? –
Asp.net। मैंने इसे प्रतिबिंबित करने के लिए मूल प्रश्न संपादित किया है। – thomasb