我有一个通过 JDBC 访问的远程数据库。这方面的网络很差,所以我有时在使用应用程序时会收到几个与网络相关的 SQLException
。
如果连接失败,我决定重试三次(间隔 2 秒)。我看到有不同的方法可以做到这一点,但我想知道我的做法是否合适。
其次,由于我使用后台服务访问数据库,如果无法建立连接,是否需要调用service.restart()
?或者只是按照我下面的实现单独重试连接就好了:
public class Sample {
public Sample() {
DatabaseService databaseService = new DatabaseService();
databaseService.start();
databaseService.setOnFailed(event->{
//do I do retries here? databaseService.restart();
});
}
public static void main(String[] args) {
new Sample();
}
private class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name) {
this.name = name;
}
}
private class DatabaseService extends Service<Person> {
@Override
protected Task<Person> createtask() {
return new GetPersonTask();
}
private class GetPersonTask extends Task<Person> {
@Override
protected Person call() throws Exception {
Connection db = DatabaseConnection.getInstance().getconnection();
//retrieve from database
return new Person("Sample");
}
}
}
}
public class DatabaseConnection {
private Connection connection;
private static DatabaseConnection instance;
private DatabaseConnection() throws SQLException {
try {
Class.forName("org.mariadb.jdbc.Driver");
String url = "jdbc:mariadb://host.com/database";
String username = "root";
String password = "";
int count = 0;
int maxTries = 3;
//3 retries in establishing connection
while (true) {
if (count == 0) {
System.out.println("INFO: Attempting remote connection to host.com");
}
try {
this.connection = DriverManager.getconnection(
url,username,password
);
break;
} catch (Exception e) {
System.out.println("ERR: Connection not established - retrying ");
Thread.sleep(2000);
if (++count == maxTries) throw e;
}
}
} catch (ClassnotFoundException | InterruptedException e) {
e.printStackTrace();
}
}
public Connection getconnection() {
return connection;
}
public static DatabaseConnection getInstance() throws SQLException {
if (instance == null) {
instance = new DatabaseConnection();
} else if (instance.getconnection().isClosed()) {
instance = new DatabaseConnection();
}
return instance;
}
}
我已将我的单例类更改为使用带有 Hikari
的池连接:
public class DatabaseConnection {
private static HikariDataSource ds;
static {
ds = new HikariDataSource();
String url = "jdbc:mariadb://host.com/database";
String username = "root";
String password = "";
ds.addDataSourceProperty("cachePrepStmts","true");
ds.addDataSourceProperty("prepStmtCacheSize","250");
ds.addDataSourceProperty("prepStmtCacheSqlLimit","2048");
ds.setMaximumPoolSize(20);
ds.setDriverClassname("org.mariadb.jdbc.Driver");
ds.setJdbcUrl(url);
ds.addDataSourceProperty("user",username);
ds.addDataSourceProperty("password",password);
ds.setautoCommit(false);
}
private DatabaseConnection() {
}
public static Connection getconnection() throws SQLException {
return ds.getconnection();
}
}