I need to implement a Java timer that tries to connect to a database for up to 2 minutes. If the connection fails within that time, an exception should be thrown.
What is the best way to achieve this in Java?
I need to implement a Java timer that tries to connect to a database for up to 2 minutes. If the connection fails within that time, an exception should be thrown.
What is the best way to achieve this in Java?
A great way to implement a Java timer for your database connection is by using ScheduledExecutorService, which allows you to run tasks at fixed intervals while keeping track of elapsed time.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.*;
public class DatabaseConnector {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
long startTime = System.currentTimeMillis();
Runnable task = () -> {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
System.out.println("Connected successfully!");
scheduler.shutdown();
} catch (SQLException e) {
if (System.currentTimeMillis() - startTime > 120_000) { // 2-minute limit
scheduler.shutdown();
throw new RuntimeException("Failed to connect within 2 minutes.", e);
}
System.out.println("Retrying...");
}
};
scheduler.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS); // Retry every 5 seconds
}
}
Why use this?
When to avoid?
If your database connection should block until success or timeout.
If you prefer a simple and blocking solution, a loop with Thread.sleep() can help.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnector {
public static void main(String[] args) throws InterruptedException {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < 120_000) { // Try for 2 minutes
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
System.out.println("Connected successfully!");
return;
} catch (SQLException e) {
System.out.println("Retrying in 5 seconds...");
Thread.sleep(5000); // Wait before retrying
}
}
throw new RuntimeException("Failed to connect within 2 minutes.");
}
}
Why use this?
When to avoid?
If you need a non-blocking or concurrent approach.
A more modern approach using CompletableFuture allows setting a timeout while attempting the database connection asynchronously.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.*;
public class DatabaseConnector {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
while (true) {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
System.out.println("Connected successfully!");
return;
} catch (SQLException e) {
System.out.println("Retrying in 5 seconds...");
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {}
}
}
}, executor);
try {
future.get(2, TimeUnit.MINUTES); // Timeout after 2 minutes
} catch (TimeoutException e) {
future.cancel(true);
throw new RuntimeException("Failed to connect within 2 minutes.", e);
} catch (Exception e) {
throw new RuntimeException("Unexpected error occurred.", e);
} finally {
executor.shutdown();
}
}
}
Why use this?
When to avoid?