單機裏面,完美解決了鎖與事務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時出錯 ------- 不能執行機率很是低