sqlitedabaseislocked問題解決

阿秀a發表於2012-11-06

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 問題解決 ,未完待續。。。。


相關文章