2011-05-12 112 views
2

我有一個應用程序,其中有數據庫活動的時間。有時我會用SQLite的'數據庫被鎖定'錯誤導致SQLiteExceptions。我曾嘗試過使用:在Android中處理sqlite'數據庫被鎖定'錯誤

if((!db.isDbLockedByCurrentThread())&&(!db.isDbLockedByOtherThreads())) { 

使用保存或插入之前,但這一直沒有成功。所以,我在課堂上設置了以下內容。 MyApplication的延伸應用,像這樣:

private AtomicBoolean writingToDataBaseFlag = new AtomicBoolean(false); 

與訪問者:

public AtomicBoolean getWritingToDataBaseFlag() { 
    return writingToDataBaseFlag; 
} 

,我想執行插入或保存我做這樣的事情的任何時間:

boolean succeeded = false; 
while(!succeeded) { 
    if(application.getWritingToDataBaseFlag().compareAndSet(false, true)) { 
     if((!db.isDbLockedByCurrentThread())&&(!db.isDbLockedByOtherThreads())) { 
      if(!activity.isFinishing()) { 
       set_id(db.insert(SDIGENRE, SDIID, cv)); 
      } 
     } 
     application.getWritingToDataBaseFlag().compareAndSet(true, false); 
     succeeded = true; 
    } else { 
    // Wait 100 millis 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

這似乎在相當長一段時間內運作良好。

  1. 這是解決此問題的正確方法嗎?
  2. 我已經開始再次看到這些錯誤;有沒有關於如何調試這個問題的建議?

感謝您的任何幫助, 朱利葉斯。

回答

1

我已經結束了我的DbHelper(SQLiteOpenHelper)綁定到我的應用程序的單個實例。通過這樣做所有的調用,我從來沒有任何併發​​問題。

0

好吧,我有機會獲得信息。並找到一篇關於線程的有趣文章操作數據庫。

在android文檔中說:isDbLockedByOtherThreads()在API 16之後被棄用。總是返回false。不要使用這種方法。

所以問題來自isDbLockedByCurrentThread();

Android的API談到的方法:

返回true,如果當前線程持有到數據庫的有效連接。

此方法的名稱來自與數據庫的活動連接意味着該線程正在數據庫上保留實際鎖定的時間。如今,不再有真正的「數據庫鎖」,儘管如果線程無法獲取數據庫連接來執行特定操作,它們可能會阻塞。

實際上,當你在android框架中的sqlitedatabase中插入,刪除,修改它關於單線程的所有內容。它意味着當你使用兩個或多個線程時操作(插入,刪除,修改)sqlitedatabase會拋出'數據庫被鎖定'的錯誤;

但是你可以打開多線程排隊一樣sqlitedatabase,它不會有任何問題

順便說一句,如果你想,當你處理插入隊列;你應該使用

getWritableDatabase().enableWriteAheadLogging(); 

它只適用於android 3。0或更高;

也許你應該讀這篇文章(如果你可以讀中文,哈哈):http://tech.techweb.com.cn/thread-621414-1-1.html