【发布时间】:2014-03-21 05:45:03
【问题描述】:
我正在开发一个使用 MySQL 来写入和读取一些数据的 java 应用程序。过了一段时间(很长一段时间)我的 jdbc 连接关闭,我在很多论坛上阅读,但我仍然无法让它永远持续下去。
我想做的是下一个:5、6、24 小时后(仍然不知道多少小时),我将关闭连接并再次连接。问题是,如果另一个线程尝试使用该连接来编写一些东西,它将在异常时失败。因此,如果 jdbc 连接正在重新启动所有需要使用 jdbc 的线程,那么我要做的下一件事就是等到重新连接完成。如果另一个线程使用该连接,我也不想阻塞线程,只有在重新启动时。我也害怕死锁:)。
我在许多论坛上阅读了有关 java 并发以及如何管理它的信息,但仍然不知道该使用什么以及如何使用它。
有用的论坛:
http://www.vogella.com/tutorials/JavaConcurrency/article.html
http://en.wikipedia.org/wiki/Java_concurrency
http://tutorials.jenkov.com/java-concurrency/index.html
编辑:
为了更清楚我想做什么
Java 数据库类:
public class Database {
//Locks
final Object readLock = new Object();
final Object writeLock = new Object();
final Object readWriteLock = new Object();
boolean enableReadLock = false;
boolean enableWriteLock = false;
//Database parametars
String user; //DB username /корисник на базата
String password; //DB password /лозинка за базата
String dbname; //DB name / име на базата
String ip; //DB Server IP address / адреса на серверот каде е базата
Connection connection; //mysql connection /
public Database(String user, String password, String dbname, String ip) throws ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
this.user = user;
this.password = password;
this.dbname = dbname;
this.ip = ip;
}
public Database(String user, String password, String dbname) throws ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
this.user = user;
this.password = password;
this.dbname = dbname;
this.ip = "localhost";
}
public void setReadLock(boolean enable) {
enableReadLock = enable;
}
/**
* Enable or disable write lock
*
* @param enable true -> enable , false -> disable
*/
public void setWriteLock(boolean enable) {
enableWriteLock = enable;
}
/**
* Enable or disable read-write lock
*
* @param enable true -> enable , false -> disable
*/
public void setReadWriteLock(boolean enable) {
enableReadLock = enable;
enableWriteLock = enable;
}
public void reconnect() throws SQLException {
connection.close();
connection = DriverManager.getConnection("jdbc:mysql://" + ip + ":3306/" + dbname, user, password);
}
public void connect() throws SQLException {
connection = DriverManager.getConnection("jdbc:mysql://" + ip + ":3306/" + dbname, user, password);
}
public void disconnect() throws SQLException {
connection.close();
}
/**
* Test connection with mysql server
*
* @return (boolean) true -> OK, false -> NOK
*/
public boolean testConnection() {
String SQL = "SELECT 1";
try {
PreparedStatement statement = connection.prepareStatement(SQL);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
}
} catch (SQLException ex) {
return false;
} catch (NullPointerException ex){
return false;
}
return true;
}
public ArrayList<HashMap<String, String>> executeSelect(String SQL) throws SQLException {
if (enableReadLock && enableWriteLock) { //Доколку има read-write lock
synchronized (readWriteLock) {
return select(SQL);
}
} else {
if (enableReadLock) { //Доколку има read-lock
synchronized (readLock) {
return select(SQL);
}
} else {
return select(SQL);
}
}
}
private ArrayList<HashMap<String, String>> select(String SQL) throws SQLException {
ArrayList<HashMap<String, String>> results = new ArrayList<>();
HashMap<String, String> row;
PreparedStatement statement = connection.prepareStatement(SQL);
ResultSet rs = statement.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int no_columns = rsmd.getColumnCount();
while (rs.next()) {
row = new HashMap<>();
for (int i = 1; i <= no_columns; i++) {
row.put(rsmd.getColumnName(i), rs.getString(i));
}
results.add(row);
}
statement.close();
rs.close();
return results;
}
public long executeInsert(String SQL) throws SQLException {
if (enableReadLock && enableWriteLock) {
synchronized (readWriteLock) {
return insert(SQL);
}
} else {
if (enableWriteLock) {
synchronized (writeLock) {
return insert(SQL);
}
} else {
return insert(SQL);
}
}
}
private long insert(String SQL) throws SQLException {
long ID = -1;
PreparedStatement statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
statement.executeUpdate();
ResultSet rs = statement.getGeneratedKeys();
if (rs.next()) {
ID = rs.getLong(1);
}
statement.close();
return ID;
}
public int executeUpdate(String SQL) throws SQLException {
if (enableReadLock && enableWriteLock) {
synchronized (readWriteLock) {
return update(SQL);
}
} else {
if (enableWriteLock) {
synchronized (writeLock) {
return update(SQL);
}
} else {
return update(SQL);
}
}
}
private int update(String SQL) throws SQLException {
PreparedStatement statement = connection.prepareStatement(SQL);
int rez = statement.executeUpdate(SQL);
statement.close();
return rez;
}
public int executeDelete(String SQL) throws SQLException {
if (enableReadLock || enableWriteLock) {
synchronized (readWriteLock) {
synchronized (readLock) {
synchronized (writeLock) {
return delete(SQL);
}
}
}
} else {
return delete(SQL);
}
}
private int delete(String SQL) throws SQLException {
PreparedStatement statement = connection.prepareStatement(SQL);
int rez = statement.executeUpdate(SQL);
statement.close();
return rez;
}
}
在重新连接方法中,我需要一些锁或其他东西,这将使每个调用选择、更新、插入或删除方法的人等待(阻塞)直到重新连接完成。
【问题讨论】:
标签: java mysql multithreading jdbc concurrency