分佈式鎖與事務

單機裏面,完美解決了鎖與事務java

1、使用鎖的緣由分析:mysql

一、使用鎖的目的redis

------------多個外部線程同時來競爭使用同一資源時,會彼此影響,致使混亂sql

------------鎖的目的,將資源的使用作排它性處理,使同一時間,僅一個線程能訪問資源數據庫

二、並非全部的資源,都沒法同時服務多個線程 ------ 好比,無狀態的資源安全

三、無成員變量/成員變量不存在變化的類---- 就是無狀態類 ----- 這種類是線程安全的服務器

四、有狀態的對象,也不必定是不安全的分佈式

---------- 若是狀態變化是原子的(即沒有中間變遷過程,變化不須要時間,沒有中間態) ---- 那麼它同樣是線程安全的工具

五、重要的概念,動做的原子性lua

六、總結:鎖的本質

鎖要解決的問題是 ------- 資源數據會不一致

鎖要達成的目標是 ------- 讓資源使用起來,像原子性同樣

鎖達成目標的手段 ------- 讓使用者訪問資源時,只能排隊,一個一個地去訪問資源

 

2、在單機應用裏,JVM能夠經過如下工具,可協調資源像原子性同樣操做

一、sychronized ------ java語言天生支持

二、lock ---- jdk有接口標準

 

3、分佈式環境下,如何協調資源達到原子性的操做?

一、sychronized / lock 這些java自然的實現,沒法跨JVM發揮做用

二、只得去尋求分佈式環境裏,你們都公認的服務來作見證人,以協調資源

三、常見的公證人 ------》 mysql/zk/file/redis

四、目標 ----- 經過公證人發出信號,來協調分佈式的訪問者,排隊訪問資源

五、條件 ----- 任何一個可以提供【是/否】信號量的事物,均可以來作公證人

六、陷阱 ----- 發出鎖信號量的動做,自己必須是原子性的

 

七、mysql來充當公證人,利用的是一條sql語句執行的成功/失敗,是原子的,流程以下:

 

 

八、redis來充當公證人,利用的其 setnx指令的成功/失敗,是原子的,流程以下:

 

 

九、爲了防止線程宕機,形成鎖死在那裏擋道,須要給鎖認定一個有效期限,

------此期限的自動失效解鎖,與線程的主動解鎖之間,會存在衝突,reids的解鎖流程必須考慮這一點:

 

 

十、上圖的解鎖邏輯雖然是正確的,但由於整個動做不是原子的,由於不安全。須要改成lua腳原本執行

 

 

十一、lua 腳本爲何是原子性的

----- redis是單線程執行指令的,所以內部不存在線程競爭

 

 

(1)服務器A依次發送了ab指令到redis

(2)服務器B依次發送了cd指令到redis

(3)兩臺機器同向redis發送的四條指令,最終在指令隊列裏順序是:acbd

(4)能夠看到,服務器A發送的ab兩條指令,中間穿插了c指令,破壞了其完整性,所以,ab兩條指令不是原子的

(5)lua腳本,被放進隊列時,ab指令是放在一塊兒的,由於ab會順序一塊兒被執行,成爲了原子性動做

 

4、事務的概念

一、鎖的問題   ----- 多對一的問題 ------ 是多個線程同時訪問同一個資源,形成資源狀態不一致

二、事務的問題 ----- 一對多的問題 ----- 是一個線程進數據庫,操做多條sql,其中,某條sql的失敗,導致整個業務失去意義;

三、數據庫中事務的實現方式:

------------------ service執行一個操做,要執行N條sql( 一條sql 是一個原子性操做)

--------- 數據庫內部,如何實現事務?

--------- 全部的sql執行完畢以前,結果都以副本形式存在,以下圖

 

 

------- commit操做 ------ 業務線程向數據庫發指令 ----- 把副本轉正

------ roback操做 ------- 把副本丟掉

四、jdbc規範裏,定義這樣標準---- 事務管理器

 

 

 

 

事務管理器定義三個標準接口,即:

一、啓動事務(啓動副本),

二、副本轉正

三、副本丟棄

 

5、分佈式事務

一、分佈式事務,是指多臺數據庫的執行sql,也想要達到一致性的標準,即:多臺一塊兒commit或rollback

二、參照單機事務的模型,分佈式事務的思路延襲,也想經過三個標準接口的模式來完成(啓副本/commit/rollback)

三、按這個思路, X/Open組織提出了分佈式事務的規範 ----- XA

四、XA的核心,即是全局事務,經過XA二階段提交協議,與各分佈式數據交互,分準備與提交兩個階段,以下圖:

 

 

 

課程回顧:

一、鎖的本質,資源的操做不是原子 -------- 鎖目標,讓一系列操做,一次性作完。排隊

二、分佈式環境下,一切可以發出兩個信號量事物都可以作鎖 ----- 作鎖要求:加鎖/解鎖兩個動做,必定是原子的

三、mysql來作鎖 ------- 一條sql的執行,是原子的

四、redis有作鎖 -------- setnx操做,是原子的

五、redis要作安全的鎖,----- 加鎖進程死掉,--------  有效期使用解鎖過程複雜化--鎖判斷----lua腳原本保證原子性

六、鎖 ---- 多個線程操做一個資源 ; 事務 ----- 一個線程,操做多個資源問題。

七、事務 ----- ACID ----- 啓事務/commit/rollback

八、X/open組織提出分佈式事務規範 ---- XA

 

 

本堂課內容:

一、事務執行的中間態說明:

----- sql執行後,還沒有提交 ,此時對應的數據狀態:

                  -----正本數據(原來的數據)   ----- 鎖定狀態-------容許其它線程讀不容許改(此時易出現幻讀)

                  -----副本數據(sql執行結果)  ------ 隔離狀態 ------其它線程是沒法接觸到的-------(可設置事務隔離級別,使其可讀)未生效的數據 ---- 髒讀

                  ----- commit/rollback時出錯     ------- 不能執行機率很是低

相關文章
相關標籤/搜索