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(); } } }