com.microsoft.sqlserver.jdbc.TDSTimeoutTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mssql-jdbc Show documentation
Show all versions of mssql-jdbc Show documentation
Microsoft JDBC Driver for SQL Server.
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/
package com.microsoft.sqlserver.jdbc;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
/**
* The TDS default implementation of a timeout command
*/
class TDSTimeoutTask implements Runnable {
private static final AtomicLong COUNTER = new AtomicLong(0);
private final UUID connectionId;
private final TDSCommand command;
private final SQLServerConnection sqlServerConnection;
public TDSTimeoutTask(TDSCommand command, SQLServerConnection sqlServerConnection) {
this.connectionId = sqlServerConnection == null ? null : sqlServerConnection.getClientConIdInternal();
this.command = command;
this.sqlServerConnection = sqlServerConnection;
}
@Override
public final void run() {
// Create a new thread to run the interrupt to ensure that blocking operations performed
// by the interrupt do not block the primary timer thread.
String name = "mssql-timeout-task-" + COUNTER.incrementAndGet() + "-" + connectionId;
Thread thread = new Thread(this::interrupt, name);
thread.setDaemon(true);
thread.start();
}
protected void interrupt() {
try {
// If TCP Connection to server is silently dropped, exceeding the query timeout
// on the same connection does not throw SQLTimeoutException
// The application stops responding instead until SocketTimeoutException is
// thrown. In this case, we must manually terminate the connection.
if (null == command) {
if (null != sqlServerConnection) {
sqlServerConnection.terminate(SQLServerException.DRIVER_ERROR_IO_FAILED,
SQLServerException.getErrString("R_connectionIsClosed"));
}
} else {
// If the timer wasn't canceled before it ran out of
// time then interrupt the registered command.
command.interrupt(SQLServerException.getErrString("R_queryTimedOut"));
}
} catch (SQLServerException e) {
// Unfortunately, there's nothing we can do if we fail to time out the request. There
// is no way to report back what happened.
assert null != command;
command.log(Level.WARNING, "Command could not be timed out. Reason: " + e.getMessage());
}
}
}