一、多進程訪問同一個數(shù)據(jù)庫是否安全
背景:多個進程代表多個數(shù)據(jù)庫操作instance,每個進程有自己的ApplicationContext。多個進程內(nèi)存不共享。
寫代碼做了測試測試代碼在最后,雖然sqlite不是線程安全的,但是在安卓多進程同時調(diào)用插入式?jīng)]有問題的,并沒有發(fā)生錯誤和沖突。因此網(wǎng)絡(luò)上也就沒有發(fā)現(xiàn)解決多進程訪問數(shù)據(jù)庫的問題,也就是不存在這樣的問題。但是,并不能保證多個進程插入的順序。
二、多進程有執(zhí)行順序要求的處理辦法
只是證明了多進程可以同時添加數(shù)據(jù),但對于有執(zhí)行順序要求的數(shù)據(jù)庫操作可能并不能滿足,即便使用了事務(wù)(事務(wù)是在線程的前提下工作的)如果真的需要考慮執(zhí)行順序但又需要多個進程同時訪問也有方法。
原理是:
1.把數(shù)據(jù)庫單獨放大一個進程里面,也就是多個進程操作最后都要經(jīng)過統(tǒng)一的入口開操作,
2.對其他進程提供接口,目的是保證數(shù)據(jù)庫操作只在一個進程里面完成
3.同時在這個進程里面使用事務(wù)或者單線程保證操作的順序。
4.保證了數(shù)據(jù)插入更改的順序,當然也就有了性能瓶頸。
實現(xiàn)方法:
1.在項目里面的所有使用數(shù)據(jù)庫的進程里,挑選其中一個作為操作數(shù)據(jù)庫的唯一進程。
2.在這個進程里面定義context provider 包裹數(shù)據(jù)庫(context provider 是用了進程間通信的安卓標準四大組件之一)
3.其他進程通過context provider 來操作數(shù)據(jù)庫
4.也就是說context provider 成為唯一的數(shù)據(jù)庫操作入口
三、sqlite處理線程不安全的方法
sqlite插入數(shù)據(jù)的時候默認一條語句就是一個事務(wù),有多少條數(shù)據(jù)就有多少次磁盤操作(可以自己寫事務(wù)代碼控制事務(wù)把多條插入語句弄到一個事務(wù)里,因為事務(wù)降低了效率)測試多進程沒有問題,也就是說在使用sqlite的時候只要考慮多線程訪問的安全。因為倆個線程同時插入會拋出異常。既然是線程安全,那么加鎖和同步代碼塊的方法(synchronized)就可以保證使用不拋出異常。
下面是對線程安全處理的示例代碼:
public synchronized void insertNewTask(int tid, int start) {//調(diào)用插入數(shù)據(jù)庫的代碼 }
public synchronized List getAllTask() {//調(diào)用讀取數(shù)據(jù)庫的代碼}
四、測試安卓多進程訪問數(shù)據(jù)是否有安全的的全部代碼
https://github.com/robert1207/DbMultProcess