用一句話簡單的說明:資料庫事務(database transaction) ,是指作為單個邏輯工作單元執行的一系列操作(對資料庫的相關增刪改查的操作),要麼完全地執行,要麼完全地不執行。
資料庫的四大特性acid,原子性、一致性、隔離性、永續性。每個特性都有其特定的職責。
2.1、原子性:乙個事務中的所有操作,要不 操作全部成功,要不全部失敗,不能存在中間態。
2.2、一致性:事務必須使得資料庫從乙個一致性狀態轉變到另乙個一致性狀態。比如銀行轉賬,a賬戶轉到b賬戶,不管轉幾次,a和b賬戶的總額不能變。
2.3、隔離性:是指多個使用者同時請求資料庫,開啟多個事務同時處理某個資料庫,隔離性保證了各個事務之間均不受干擾,每個事務都感覺不到其他事務的存在。
2.4、永續性:對資料庫的修改是永續性的,一旦修改,就算資料庫系統出現故障,這種修改也不會丟失,這點是資料庫資料存放到硬碟中,並有redo log 和 binlog 一起保證的。
隔離級別一共有四種:讀未提交、讀已提交、可重複讀、序列化。這四種隔離級別分別可以解決的不同的問題,下面先描述一下不使用隔離級別可能會出現的幾種問題。
(1)丟失修改
a和b兩個事物同事修改同乙個資料,a修改的提交在b提交之後,導致b好像沒有修改,丟失修改。
(2)髒讀
b事務修改了乙個資料並未提交,a事物讀取了這個資料,然後b事務回滾了,最後a又讀取了一次,兩次讀取的資料不一致,稱為髒讀。
(3)不可重複讀
a事務讀取了乙個資料後,b事務修改了這個資料,a事務又讀取了這個資料,兩次讀取的資料也不一致,稱為不可重複讀。
(4)幻讀
a事務更新了某個字段(範圍是整個資料表的)(以id=1為條件的),b事務又插入了一條新的記錄,導致a事務認為自己沒有完全更新過來,就像出現幻覺一樣。
針對這幾種錯誤分別設定不同的隔離級別來解決:
第一種丟失修改一般使用加鎖鎖來解決,因此序列化可以解決,並且序列化可以解決上面出現的所有問題。
第二種問題髒讀是因為讀取其他事物未提交的資料,因為設定讀已提交隔離級別可以解決這個問題。但不可解決不可重複讀和幻讀的問題。
第三種問題不可能重複讀,是因為b事物的修改影響了a事務的讀取資料,設定可重複讀隔離級別,使得b事務修改資料和a事務讀取資料互不影響,隔離開來,從而解決這個問題,同時解決 髒讀問題。
第四種幻讀問題,是因為a事務更新完資料後,b事務又插入了新的資料,設定序列化隔離級別可解決,並且這種隔離級別解決上面所有的問題。除了序列化,
多版本併發控制(mvcc, multiversion concurrency control)機制也可以解決該問題。
innodb的mvcc,是通過在每行記錄後面儲存兩個隱藏的列來實現的,這兩個列,分別儲存了這個行的建立時間(系統版本號,沒開啟新事物自動遞增)和刪除時間(當刪除這行資料時,使當 前系統版本號作為刪除時間)。這裡儲存的並不是實際的時間值,而是系統版本號 (可以理解為事務 的id),每開始乙個新的事務,系統版本號就會自動遞增,事務開始時刻的系統版本號會作為 事務的id.不同版本號的行記錄相當於記錄的乙個快照,不同的事務在不同的快照上處理自己的操 作,互不影響。
select時的規則要求
innodb會根據以下兩個條件檢查每行記錄:
a.innodb只會查詢版本早於當前事務版本的資料行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插 入或者修改過的.
b.行的刪除版本要麼未定義,要麼大於當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.
只有a,b同時滿足的記錄,才能返回作為查詢結果.
引用:spring通過配置事務的傳播屬性來嚴格控制事務行為。比如 在乙個配置了事務的方法中呼叫了另乙個方法,則另乙個方法應該怎麼執行,是新開啟乙個事務,還是和呼叫方法是乙個事務,還 是 不開啟事務?一共有七種傳播屬性。
分布式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。當資料庫的資料越來越大,資料庫無法承受起壓力,就會開始分庫分表,分庫分表後不同的庫就會分布在不同的伺服器上,明顯的就會出現資料一致性問題。或者同乙個事務中要呼叫的不同系統的不同的庫,也要保證要不全都成功,要不全部回滾。
如何解決分布式事務資料一致性問題,下面分別總結幾種方案。
(1)兩階段提交
事務協調器首先會將prepare訊息寫入日誌中,然後向ab資料庫發出prepare訊息,操作完成後先不提交,而是返回yes,如果事務協調器收到的返回都是yes,則全部執行提交。如果有乙個不 是yes,則向所有的執行器傳送abort(退出、回滾)操作。
這種兩階段提交的方式能夠保證資料一致性。但是犧牲了一定的可用性。
優點:盡量保證了資料的強一致,適合對資料強一致要求很高的關鍵領域。(其實也不能100%保證強一致)
缺點:實現複雜,犧牲了可用性,對效能影響較大,不適合高併發高效能場景,如果分布式系統跨介面呼叫,目前 .net 界還沒有實現方案。
(2)三段式提交協議
在二階段提交的基礎上,在提交的時候,先發出precommit(預提交),當所有的執行器返回yes,在最終發出提交操作申請。否則向所有的執行器傳送abort(退出)請求。
最大優點就是降低了參與者的阻塞範圍,並且能夠在出現單點故障後繼續達成一致。
缺點就是在去除阻塞的情況下引入了新的問題,那就是參與者接收到了precommit訊息,然後網路出現問題,參與者和協調者無法通訊,這種情況下,參與者依然會執行事務的提交。
(3)補償事務(tcc)
簡單舉個例子說明,比如乙個借錢產品,你發起借錢時,你的可借額度會被凍結,借錢成功,扣減額度並解凍。借錢失敗則解凍額度,如果可藉額度發生變化,還需要回滾額度。
優點:跟2pc比起來,實現以及流程相對簡單了一些,但資料的一致性比2pc也要差一些
缺點:缺點還是比較明顯的,在2,3步中都有可能失敗。tcc屬於應用層的一種補償方式,所以需要程式設計師在實現的時候多寫很多補償的**,在一些場景中,一些業務流程可能用tcc 定義及處理。
(4)本地訊息表
訊息生產方,需要額外建乙個訊息表,並記錄訊息傳送狀態。訊息表和業務資料要在乙個事務裡提交,也就是說他們要在乙個資料庫裡面。然後訊息會經過mq傳送到訊息的消費方。如果訊息 發 送失敗,會進行重試傳送。
訊息消費方,需要處理這個訊息,並完成自己的業務邏輯。此時如果本地事務處理成功,表明已經處理成功了,如果處理失敗,那麼就會重試執行。如果是業務上面的失敗,可以給生產方傳送 乙個業務補償訊息,通知生產方進行回滾等操作。
優點:一種非常經典的實現,避免了分布式事務,實現了最終一致性。在 .net中 有現成的解決方案。
缺點:訊息表會耦合到業務系統中,如果沒有封裝好的解決方案,會有很多雜活需要處理。
(5)基於可靠訊息服務的分布式事務
有一些第三方的mq是支援事務訊息的,比如rocketmq
原文:
參考:
資料庫事務總結
資料庫併發訪問會出現以下4種問題 1 第一類丟失更新 事務b巢狀在事務a中,事務b已經更新,之後事務a更新失敗,a回滾,丟失了b的更新。支援事務的資料庫不會出現此問題 2 髒讀 讀到其他事務還未提交的資料。3 不可重複讀 在同一事務中,兩次讀取的資料不一致。被其他事務修改了 4 幻讀 兩次讀取的記錄...
資料庫 索引 事務總結
一 索引 1 什麼是索引 索引是一種特殊的資料庫結構,它包含著對資料表裡所有記錄的引用指標,根據這個指標我們就可以找到這個指標所對應的記錄。可以對錶中的一列或多列建立索引,並指定索引的型別,各類索引有各自的資料結構實現。從某種程度上說,索引就相當於一本書的目錄,根據這個目錄中所寫的頁碼我們就能更快的...
資料庫總結 事務篇
巨集觀角度 應用程式設計師 乙個訪問或改變資料庫內容的程式的一次執行,或者說一條或多條sql語句一次執行被看作乙個事務。事務是資料庫管理系統提供的控制資料操作的一種手段,通過這一手段,應用程式設計師將一系列的資料庫操作組合在一起作為乙個整體進行操作和控制,以便資料庫管理系統能夠提供一致性狀態轉換的保...