[ACCEPTED]-How to track database connection leaks-connection-leaks
When looking at the code from the SQL Server 8 side you can run the following query to 7 get a view on which queries are last run 6 on sleeping connections. (open connections 5 which are doing nothing)
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'
From the application 4 side you can debug with sos.dll as described 3 in the following articles:
- How to troubleshoot leaked SqlConnection Objects Part 1
- How to troubleshoot leaked SqlConnection Objects Part 2
If you need more 2 information on how to use windbg, these 1 articles are a good intro:
The best way to tackle connection leaks 8 is to do it during testing.
You can use an 7 automated utility so that each test verifies 6 if there is a connection leak.
@BeforeClass
public static void initConnectionLeakUtility() {
if ( enableConnectionLeakDetection ) {
connectionLeakUtil = new ConnectionLeakUtil();
}
}
@AfterClass
public static void assertNoLeaks() {
if ( enableConnectionLeakDetection ) {
connectionLeakUtil.assertNoLeaks();
}
}
The ConnectionLeakUtil
looks 5 like this:
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 );
}
}
}
The IdleConnectionCounter
implementations can be found 4 in this [blog post][1], and the MySQL version 3 like this:
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 );
}
}
}
Now, when you run your tests, you'll 2 get a failure when a connection is being 1 leaked:
:hibernate-core:test
org.hibernate.jpa.test.EntityManagerFactoryClosedTest > classMethod FAILED
org.hibernate.testing.jdbc.leak.ConnectionLeakException
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.