1、sqlite
database is locked問題解決
在使用synchronized無效的情況下,今天嘗試瞭如下幾中方案ThreadLocal,和重入鎖ReentrantLock兩種方案
A、ThreadLocal方式
public ThreadLocal<Connection> threadLocal=new ThreadLocal<Connection>();
public Connection getConnection(){ {
Connection conn=null;
if(threadLocal.get()==null){
conn=DriverManager.getConnection(URL);
threadLocal.set(conn);
return conn;
}else{
return (Connection)threadLocal.get();
}
}
public void closeConnection() throws SQLException{
Connection conn=(Connection)threadLocal.get();
threadLocal.set(null);
if(conn!=null){
conn.close();
conn=null;
}
}
說明:如果對ThreadLocal理解透徹,顯而易見,對於一個執行線程而言得到的是同一個數據庫連接,不同的線程得到的是不同的數據庫連接。所以我們說實現了線程安全的數據庫連接。如果深入研究ThreadLocal類,SUN是這樣解釋,由一個HashMap維護每一個線程獨立擁有的變量,HashMap的鍵值就是線程的序號,SUN公佈了部分API的實現細節,有興趣的朋友也可以自己試着來實現這個ThreadLocal類。
OK大功靠成!,之前必現的locked問題得到解決!
B、採用重入鎖ReentrantLock對鏈接的創建和關閉進行手動加鎖
public Connection getConnection(){
lock.lock();
Connection conn = null;
try {
conn = DriverManager.getConnection(URL);
}catch(SQLException e) {
lock.unlock();
throw e;
}
return conn
}
public void closeConnection(Connection conn) {
if(conn!=null){
conn.close();
conn=null;
}
lock.unlock;
}
採用這種方式遇到了如下問題:
(1) 由於我只在dispose(Conn)方法中調用了unlock,雖然出現的概率降低,但偶爾還是會出現
後來在所有 關閉Conn的方法中都unlock,這個問題也不再出現了!
(2)、使用Lock的情況下,方法上還有synchronized關鍵字的情況 下,導致死鎖,界面卡死,程序不動了!
去掉synchronized修飾符,解決該問題!
總結:這個問題糾結了我兩天時間,纔開始考慮從SQLITE本身來找問題,網絡上的千篇一律,後來想SQLITE使用的是非常廣泛的,應該不至於這麼爛,於是,首先是排查所有DAO操作,檢查是否存在Conn等數據庫資源沒有釋放的;另外就是從程序層面使用鎖或者線程安全方面來考慮,終得解決!嘻嘻。。。。
sqlite dabase is locked 問題解決 ,未完待續。。。。