I have a problem with my JDBC SQLite database: when trying to drop the tables I get the error saying that a table is locked. The strange thing is that I get different results with the same code on different places. I know this question is already asked here, but I close all my resultsets and (prepared)statements.
This is my OfflineDB.java file:
public String sendMessage(String processInstanceId) {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
String request = "<SOAP:Envelope xmlns:" + "SOAP='http://schemas.xmlsoap.org/soap/envelope/'>" + "<SOAP:Body>"
+ "<SendMessage xmlns='http://schemas.cordys.com/bpm/execution/1.0'>" + "<receiver>" + processInstanceId
+ "</receiver>" + "<message overwrite='false' />" + "</SendMessage>" + "</SOAP:Body>"
+ "</SOAP:Envelope>";
SendMessageAPI sendMessageObject = new SendMessageAPI();
StreamSource source = new StreamSource(new StringReader(request));
StreamResult result = new StreamResult(System.out);
System.out.println("called service" + request);
webServiceTemplate.sendSourceAndReceiveToResult(
"url",
source, result);
return "Success";
Simple: it just opens a connection on creation and stores this connection.
I have a JUnit test for this class, and this test runs perfectly:
public enum OfflineDB {
UNIQUEINSTANCE;
private Connection conn = null;
private OfflineDB(){
try {
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
conn = DriverManager.getConnection("jdbc:sqlite:" +
System.getProperty("user.dir") + "\\database.db");
setupDB();
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
public Connection getConnection(){
return conn;
}
public void setupDB(){
Statement stmt = null;
try {
stmt = conn.createStatement();
stmt.closeOnCompletion();
stmt.execute(CREATE_CAR);
stmt.execute(CREATE_DTTS);
stmt.execute(CREATE_CHDT);
stmt.execute(CREATE_USER);
stmt.execute(CREATE_CIRCUIT);
stmt.execute(CREATE_CSD);
stmt.execute(CREATE_DASHBOARD);
stmt.execute(CREATE_ICW);
stmt.execute(CREATE_TILE);
stmt.execute(CREATE_TSD);
stmt.execute(CREATE_ISUPDATED);
stmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
} finally{
try {
stmt.close();
} catch (SQLException | NullPointerException e) {
e.printStackTrace();
}
}
}
public boolean dropTables(){
Statement stmt = null;
try {
stmt = conn.createStatement();
stmt.closeOnCompletion();
stmt.execute(DROP_DTTS);
stmt.execute(DROP_CHDT);
stmt.execute(DROP_TSD);
stmt.execute(DROP_CSD);
stmt.execute(DROP_ICW);
stmt.execute(DROP_CAR);
stmt.execute(DROP_CIRCUIT);
stmt.execute(DROP_DASHBOARD);
stmt.execute(DROP_TILE);
stmt.execute(DROP_USER);
stmt.execute(DROP_ISUPDATED);
stmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
System.out.println(ex.getErrorCode());
return false;
} finally{
try {
stmt.close();
} catch (SQLException | NullPointerException e) {
e.printStackTrace();
}
}
return true;
}
In another class I try to run the same code as this test, but here I get the error saying that the database is locked:
@Test
public void testDropTables(){
Boolean bool = OfflineDB.UNIQUEINSTANCE.dropTables();
assertTrue(bool);
}
I also wrote a JUnit for this and when I try to run the test, the error occurs, if I immediately run the previous test after this one, this gives no problem.
public boolean syncDatabases(){
if(!checkIsUpdated()) return false;
else{
System.out.println("syncing databases");
if(!OfflineDB.UNIQUEINSTANCE.dropTables()) return false;
}
return true;
}
public boolean checkIsUpdated(){
boolean updateNeeded = false;
//check if the online timestamp is later than the offline
Timestamp online = getLastUpdated(true);
Timestamp offline = getLastUpdated(false);
System.out.println("online: " + online + " offline: " + offline);
if(getLastUpdated(true).after(getLastUpdated(false)))
updateNeeded = true;
return updateNeeded;
}
The error:
@Test
public void testSyncDatabases() {
System.out.println("syncDatabases");
boolean expResult = true;
boolean result = SyncMapper.UNIQUEINSTANCE.syncDatabases();
assertEquals(expResult, result);
}
答案 0 :(得分:1)
显然我错了:还有一个结果集没有关闭......对于将来遇到同样问题的人:请确保在返回后不关闭结果集或准备好的结果。在我的情况下,我在try / catch中的if / else结构中返回了一个时间戳,然后在if / else之后我关闭了resultset和preparedstatement,这导致代码永远不会到达这些行。