我們知道Android系統(tǒng)支持sqlite數(shù)據(jù)庫,使用Android系統(tǒng)訪問sqlite數(shù)據(jù)庫時(shí),有時(shí)可能會(huì)遇到android.database.sqlite.SQLiteException: database is locked異常,例如
06-29 13:17:12.415: E/Database(10064): CREATE TABLE android_metadata failed
06-29 13:17:12.455: E/Database(10064): Failed to setLocale() when constructing, closing the database
06-29 13:17:12.455: E/Database(10064): android.database.sqlite.SQLiteException: database is locked
06-29 13:17:12.455: E/Database(10064): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
06-29 13:17:12.455: E/Database(10064): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987)
06-29 13:17:12.455: E/Database(10064): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1855)
06-29 13:17:12.455: E/Database(10064): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
遇到這個(gè)問題,有幾種可能,我在下面詳細(xì)的列出來,方便大家在遇到的時(shí)候查看
多線程訪問造成的數(shù)據(jù)庫鎖定。
如A線程在訪問當(dāng)前的數(shù)據(jù)庫,這時(shí)候B線程也需要訪問數(shù)據(jù)庫,這樣在B線程中,就會(huì)有類似以上的異常產(chǎn)生,我們需要將提供數(shù)據(jù)庫訪問的方法設(shè)置成同步的,防止異步調(diào)用時(shí)出現(xiàn)問題,如:
public static synchronized DBConnection getConnection(String connectionName)
throws Exception {
String pathFile = getPath() connectionName;// 轉(zhuǎn)換目錄data下
return new DBConnection(SQLiteDatabase.openDatabase(pathFile, null,
SQLiteDatabase.OPEN_READWRITE));
}
使用synchronized 關(guān)鍵字來修飾獲取數(shù)據(jù)庫連接的方法,或者使用 isDbLockedByOtherThreads方法判斷數(shù)據(jù)庫是否被鎖住了,然后等待一定的時(shí)間再進(jìn)行訪問。
sqlite自身的問題
有時(shí)我們會(huì)在調(diào)試程序的時(shí)候發(fā)現(xiàn)Log控制臺(tái)頻繁的出現(xiàn)上述異常,而在運(yùn)行程序的時(shí)候就沒有這個(gè)問題,這種現(xiàn)象我在調(diào)試ResultSet時(shí)也會(huì)出現(xiàn),查資料找原因是因?yàn)閟qlite數(shù)據(jù)不完全是線程安全的,導(dǎo)致在一些地方會(huì)莫名其妙的出問題,如果遇到這樣的情況,那只能不要將斷點(diǎn)打到數(shù)據(jù)庫連接的地方了。
|