android 數據庫操作的注意事項

1.儘量用事務完成一套數據庫操作流程。

雖然代碼邏輯驗證沒問題,但還是會有低概率的異常,導致一個流程的數據庫操作會中途出錯,導致更嚴重的錯,如系統IO繁忙等錯誤。錯誤例子如下

public void test(AlarmData oldData, AlarmData newData) {
    try {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.delete(TABLE_NAME, null, null);
        ContentValues cValue = new ContentValues();
        cValue.put(COLUMN_HOUR, newData.hour);
        cValue.put(COLUMN_MINUTE, newData.minute);
        cValue.put(COLUMN_REPEAT, newData.repeat);
        cValue.put(COLUMN_ENABLE, newData.isEnable);
        cValue.put(COLUMN_VIBRATE, newData.vibrate);
        cValue.put(COLUMN_MUSIC, newData.music);
        //執行插入時出現IO問題,插入失敗,導致出現空表的異常問題
        db.insert(TABLE_NAME, null, cValue);
    } catch (Exception e) {

    }
}

2.架構數據庫儘量考慮併發讀寫問題。

雖然目前項目功能和需求簡單,不會觸及併發,但也要考慮。解決併發問題,可以參考如下:

1.ContentProvider,同一時間只讀寫

2.同步鎖避免數據庫多次打開和關閉問題

private SQLiteDatabase mWritableDb;
private AtomicInteger mOpenCounter = new AtomicInteger();
private final static Object sSyncLock = new Object();
SQLiteDatabase getWritableDb() {
   synchronized (sSyncLock) {
      if (mWritableDb == null || !mWritableDb.isOpen()) {
         mWritableDb = SQLiteDatabase.openDatabase(mContext.getDatabasePath(DB_NAME).getPath(),
               null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READWRITE);
         mOpenCounter.lazySet(0);
      }
      mOpenCounter.incrementAndGet();
   }
   return mWritableDb;
}

synchronized void closeWritableDb() {
   synchronized (sSyncLock) {
      if (mWritableDb != null && mWritableDb.isOpen() && mOpenCounter.decrementAndGet() == 0) {
         mWritableDb.close();
      }
   }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章