處理事務的常見方法有排隊法、排他鎖、讀寫鎖、
mvcc
等方式。
事務處理中最重要也是最簡單的方案是排隊法,單執行緒地處理一堆資料。
在redis
中,如果資料全部在記憶體中,那麼單執行緒處理所有
put、
get操作效率最高。原因在於多執行緒的本質是
cpu模擬多個執行緒,這種模擬是以上下文切換為代價,這種上下文切換是需要額外開銷的,而對於記憶體的資料庫來說,沒有上下文切換時效率最高。因此,單個
cpu繫結一塊記憶體的資料,針對這塊資料做多次讀寫操作時都是在單個
cpu上完成的,單執行緒處理方式在記憶體的情況是效率是最優的。
那麼什麼時候事務需要用到多執行緒呢?這個問題的本質取決於下層所使用的儲存,如果是記憶體操作,則可以動態地申請和銷毀
記憶體塊;而磁碟的
iops
很低,但吞吐量很高。
如果乙個場景涉及多次讀寫操作,單執行緒可以很高的效率對於記憶體進行讀寫操作;但是,由於磁碟的
iops
僅為記憶體的幾千分之
一,如果依舊用操作記憶體的方式操作磁碟,那系統的整體效能將會很低,這意味著必須將大量的讀寫操作聚合成乙個
batch
後再提交
時才能達到較好的效能。而將大量請求攢到一起的方式一是非同步,也就是請求本身和執行緒不繫結,執行緒可以不
block
(本質來說還是
一種多執行緒的方式),處理完乙個執行緒後再處理其他執行緒。這種做法的核心是將大量不同的請求提交到乙個
buffer
中,再由該
buffer
統一讀取或者寫入磁碟,從而提高效率。在慢速裝置中,多執行緒或非同步非常常見,在設計系統時,面對磁碟、網路、
ssd等慢速設
備必須考慮使用多執行緒。
有些場景不適合用單執行緒操作,可以利用排他鎖的方式來快速隔離併發讀寫事務。
若事務t對資料物件a加上x鎖,則只允許t讀取和修改a,其他任何事務都不能再對a加任何型別的鎖,直到t釋放a上的鎖。這就保證了其他事務在t釋放a上的鎖之前不能再讀取和修改a。
讀寫鎖資料庫中有一些事務單元是共享的,如果是乙個唯讀的事務,例如只對資料進行查詢操作,在該過程中資料一定不被修改,因此多個查詢操作可以並行執行,因此一種針對讀讀場景的優化自然而然產生
——讀寫鎖。讀寫鎖的核心是在多次讀的操作中,同時允許多個讀者
來訪問共享資源
,提高併發性。
mvcc
在最初的資料庫事務實現中是不存在
mvcc
的,它是
oracle
在八十年代新加的功能,本質是
copy on write
,也就是每次寫都是以重新開始乙個新的版本的方式寫入資料,因此,資料庫中也就包含了之前的所有版本。在資料讀的過程中,先申請乙個版本號,如果該版本號小於正在寫入的版本號,則資料一定可以查詢到,無需等到新版本完全寫完即可返回查詢結果。這種方式可以在讀讀不阻塞的前提下,實現讀寫
/寫讀不阻塞,盡可能保證所有的讀操作並行,而寫操作序列。
分布式事務處理
前提如下 db a,db b為兩個資料庫 都有乙個person表 該錶兩個字段 personid 主鍵 和personname 下面的分布式事務 實現的是 同時向這兩個庫的兩個表新增資料 set xact abort on 開始分布式事務 begin distributed transaction ...
分布式事務處理
場景 a資料庫有乙個人叫小明,b資料庫有乙個人叫小花,現在小明要給小花轉賬100,那麼就有兩個操作,小明賬戶 100,小 花賬戶 100,由於是跨資料庫,事務在此時沒用,那該如何保證兩人賬戶資料的準確。方案一 兩次提交,設計理念 在同乙個資料庫中,我們可以使用事務來保證資料的原子性。現在我們有兩個資...
java 分布式事務處理
分布式事務處理 當資料分布在多個資料庫伺服器上時,就需要各種保護措施來保證資料正確地寫到所有資料庫中。例如,考慮乙個在三個分離的遠端資料庫上修改的 客戶帳戶平衡表,如果在事務寫階段,任何乙個資料庫連線失敗,資料庫之間就失去同步。怎樣檢測並更正這種情形呢?事務處理 tp 監示乙個叫做兩階段提交 的過程...