併發與事務

2021-07-27 03:21:03 字數 1658 閱讀 6026

本部落格只是在開發過程中,對遇到的多執行緒問題的思考,如何在保證資料正確的前提下,提高效能。

我覺得併發要考慮兩個問題:

在io層次,併發鏈結數過多例如c10k,c10m的問題,是通過reactor'模式解決?例如開源的網路庫都是使用單執行緒io復用+非阻塞的思想解決,最優!還是通過乙個連線對應乙個執行緒,或者是說執行緒池解決。

通常來說,io復用解決io問題,執行緒池+阻塞佇列解決計算密集型的問題

多執行緒,多程序的併發問題,併發讀寫怎麼解決?資料如何可以不髒不亂?

併發問題可以通過mvcc(多版本,寫時複製),鎖,條件變數等機制來解決。一般來說,多執行緒併發問題用鎖來解決。

併發讀寫最好就從架構上解決問題,達到無鎖。如果有鎖,那麼執行緒掛起,執行緒切換是有開銷的,可以鎖住之後,其他程序就要等待,這併發度可想而知。

解決:例如乙個執行緒只操作乙個劃分的子區域,乙個邏輯佇列等。

可以用單執行緒解決就不要用多執行緒,可以無鎖解決就不要加鎖。例如redis用單執行緒解決了執行緒切換,資料併發衝突問題,hash解決資料一致性問題,主從同步解決可靠性問題。

問題

如何保證乙個操作的完整性呢,例如乙個寫著在寫,乙個讀者讀,怎麼辦?

解決

設乙個寫入標誌位,只有寫入成功,讀者才可以讀,否則阻塞,或者返回空。這樣當讀者可以讀資料的時候,讀到的都是完整的資料,但是2個寫者如果同時寫資料,還是有衝突,因此一段區域不能有2個寫者。

問題

如果乙個讀者在讀,如果乙個寫著準備將資料刪除呢?

解決1

設乙個刪除標誌位,讀者讀完檢查刪除標誌位,如果刪除標誌位至為1,則返回空(或者事物回滾),否則返回讀到的內容。

解決2

寫者先將刪除標誌位設為1,等待一段時間(如果設為標誌位之前有讀者在讀,應該讀完畢的時間),然後刪除資料(或者最後由**程序刪除資料),如果多個寫者同時刪資料,可能會有資料不存在的異常。感覺不靠譜。

問題

如果寫者對資料要修改?

解決1

只能使用先刪除,後寫入的邏輯,讀到的資料具有不確定性,可能是新資料,也可能是老資料,因為執行緒切換的**點,誰也不知道。也有可能讀不到資料啊,但是資料真的有,只是在修改,這是個大問題。難道設個標誌位修改中,這樣不是讓讀者全部阻塞了。。不靠譜,併發度不行啊。

解決2

寫時複製,如果是修改,則另外新寫資料,不影響讀者讀老資料,只有資料寫入成功後,更換老版本?還是保留版本。

結論

乙個寫著,多個讀者的問題可以通過乙個寫入標誌位和乙個刪除標誌位解決。

問題

如果是多個寫者呢?

解決

每個寫者寫一部分區域,分而治之的思想,大化小+hash對映。。。。。

總結

併發,多執行緒,事務都是分不開的。

事務與併發

一 首先我們先來看段 conn.setautocommit false int count1 utilconn.updatedata conn,update dict cost subj set is hr 0 if count1 1 else 這斷 經過資料庫跟蹤是 img set implici...

事務與併發(2)

事務與併發 2 事務由作為包執行的單個命令或一組命令組成。通過事務可以將多個操作合併為單個工作單元。如果在事務中的某一點發生故障,則所有更新都可以回滾到其事務前狀態。事務必須符合 acid 屬性 原子性 一致性 隔離和永續性 才能保證資料的一致性。大多數關係資料庫系統 例如 microsoft sq...

事務與併發控制

所謂事務是使用者定義的乙個資料操作序列,這些操作可作為乙個完整的工作單元,要麼全部執行,要麼全部不執行,是乙個不可分割的工作單位.事務中的操作一般是對資料的更新操作,包括增,刪,改.事務的特徵 原子性 atomicity 一致性 consistency 隔離性 isolation 持續性 durab...