這兩天一直在搗鼓SQLite數據庫,基本的操作就不說了,比較簡單,打算有空的話另起一篇博文簡單總結一下。
這里主要想探討一下多路并發下的數據庫操作
SQLite作為一款小型的嵌入式數據庫,本身沒有提供復雜的鎖定機制,無法內部管理多路并發下的數據操作同步問題,更談不上優化,所以涉及到多路并發的情況,需要外部進行讀寫鎖控制,否則SQLite會返回SQLITE_BUSY錯誤,以駁回相關請求。
如果有朋友想了解SQLite相關的鎖定機制,可以看看我轉載的博文sqlite的事務和鎖,講解的比較透徹,也容易理解,這里就不再重復講解了。
返回SQLITE_BUSY主要有以下幾種情況:
1。當有寫操作時,其他讀操作會被駁回2。當有寫操作時,其他寫操作會被駁回3。當開啟事務時,在提交事務之前,其他寫操作會被駁回4。當開啟事務時,在提交事務之前,其他事務請求會被駁回5。當有讀操作時,其他寫操作會被駁回6。讀操作之間能夠并發執行
基于以上討論,可以看出這是一個典型的讀者寫者問題,讀操作要能夠共享,寫操作要互斥,讀寫之間也要互斥可以設計如下的方案解決并發操作數據庫被鎖定的問題,同時保證讀操作能夠保持最大并發1。采用互斥鎖控制數據庫寫操作2。只有擁有互斥鎖的線程才能夠操作數據庫3。寫操作必須獨立擁有互斥鎖4。讀操作必須能夠共享互斥鎖,即在第一次讀取的時候獲取互斥鎖,最后一次讀取的時候釋放互斥鎖
具體的代碼實現就不貼了,有了思路,實現就很簡單了,歡迎大家一起討論!
下面是我簡單編寫的一個共享鎖,smutex是一個跨平臺的鎖實現,簡單,不多說了:// 共享鎖,第一個進入時鎖定,最后一個離開時釋放class shared_mutex{PRivate:static int taked_man_; // 當前持有該鎖的線程數static sp::smutex man_lock_; // taked_man_的修改鎖
private:// 自動模式bool is_auto_;sp::smutex *mutex;public:void aquire(){ sp::sguard<sp::smutex> auto_lock(shared_mutex::man_lock_); if(taked_man_ == 0) { mutex->acquire(); } taked_man_++;}void release(){ sp::sguard<sp::smutex> auto_lock(shared_mutex::man_lock_); if(this->taked_man_ > 0) { taked_man_--; if(taked_man_ == 0) { mutex->release(); } }}public:shared_mutex(sp::smutex &mt, bool auto_ = true) : mutex(&mt){ sp::sguard<sp::smutex> auto_lock(shared_mutex::man_lock_); this->is_auto_ = auto_; if(this->is_auto_) { this->aquire(); }}
~shared_mutex(){ sp::sguard<sp::smutex> auto_lock(shared_mutex::man_lock_); if(this->is_auto_) { this->release(); }}
};
http://blog.csdn.net/bestrem_9/article/details/6322916
新聞熱點
疑難解答