這兩天一直在搗鼓SQLite數(shù)據(jù)庫(kù),基本的操作就不說了,比較簡(jiǎn)單,打算有空的話另起一篇博文簡(jiǎn)單總結(jié)一下。
這里主要想探討一下多路并發(fā)下的數(shù)據(jù)庫(kù)操作
SQLite作為一款小型的嵌入式數(shù)據(jù)庫(kù),本身沒有提供復(fù)雜的鎖定機(jī)制,無法內(nèi)部管理多路并發(fā)下的數(shù)據(jù)操作同步問題,更談不上優(yōu)化,所以涉及到多路并發(fā)的情況,需要外部進(jìn)行讀寫鎖控制,否則SQLite會(huì)返回SQLITE_BUSY錯(cuò)誤,以駁回相關(guān)請(qǐng)求。
如果有朋友想了解SQLite相關(guān)的鎖定機(jī)制,可以看看我轉(zhuǎn)載的博文sqlite的事務(wù)和鎖,講解的比較透徹,也容易理解,這里就不再重復(fù)講解了。
返回SQLITE_BUSY主要有以下幾種情況:
1。當(dāng)有寫操作時(shí),其他讀操作會(huì)被駁回2。當(dāng)有寫操作時(shí),其他寫操作會(huì)被駁回3。當(dāng)開啟事務(wù)時(shí),在提交事務(wù)之前,其他寫操作會(huì)被駁回4。當(dāng)開啟事務(wù)時(shí),在提交事務(wù)之前,其他事務(wù)請(qǐng)求會(huì)被駁回5。當(dāng)有讀操作時(shí),其他寫操作會(huì)被駁回6。讀操作之間能夠并發(fā)執(zhí)行
基于以上討論,可以看出這是一個(gè)典型的讀者寫者問題,讀操作要能夠共享,寫操作要互斥,讀寫之間也要互斥可以設(shè)計(jì)如下的方案解決并發(fā)操作數(shù)據(jù)庫(kù)被鎖定的問題,同時(shí)保證讀操作能夠保持最大并發(fā)1。采用互斥鎖控制數(shù)據(jù)庫(kù)寫操作2。只有擁有互斥鎖的線程才能夠操作數(shù)據(jù)庫(kù)3。寫操作必須獨(dú)立擁有互斥鎖4。讀操作必須能夠共享互斥鎖,即在第一次讀取的時(shí)候獲取互斥鎖,最后一次讀取的時(shí)候釋放互斥鎖
具體的代碼實(shí)現(xiàn)就不貼了,有了思路,實(shí)現(xiàn)就很簡(jiǎn)單了,歡迎大家一起討論!
下面是我簡(jiǎn)單編寫的一個(gè)共享鎖,smutex是一個(gè)跨平臺(tái)的鎖實(shí)現(xiàn),簡(jiǎn)單,不多說了:// 共享鎖,第一個(gè)進(jìn)入時(shí)鎖定,最后一個(gè)離開時(shí)釋放class shared_mutex{PRivate:static int taked_man_; // 當(dāng)前持有該鎖的線程數(shù)static sp::smutex man_lock_; // taked_man_的修改鎖
private:// 自動(dòng)模式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
新聞熱點(diǎn)
疑難解答
圖片精選