## 避不開的分布式事務
https://mp.weixin.qq.com/s?__biz=MzU1MzYwMjQ5MQ==&mid=2247485412&idx=1&sn=66560e9c6f84f0d634acd35527edc70f&chksm=fbf11b30cc8692262f3c438b64bd6b6181787b7eb01b17a2d42d6859def28b10a3c683f0befb&scene=132#wechat_redirect
原創Code綜藝圈[Code綜藝圈](javascript:void(0);)*昨天*
收錄于話題
#分布式事務1
#微服務那些事15
### 前言
關于前面系列的文章已經說到分布式服務之間的通信,則分布式事務接下來就是我們要一起學習的主題,走起。
數據庫事務在現有大大小小的系統中幾乎是避免不開的,或多或少總會有一些業務關聯在一塊;對于單機事務的應用場景和操作,相信小伙伴已經夠熟練了;隨著分布式、微服務的開發模式普及,分布式事務落地也成為了程序員的必備之技,接下來的幾篇一起來學習和實操。
### 正文
#### 1\. 事務回顧
##### 1\. 1 事務簡介
通俗一點理解就是**將一組對數據的操作(增、刪、改、查)看做成一個邏輯單元,要么都執行,要么都不執行,確保數據一致性**。
##### 1.2 事務特性(ACID)
* 原子性(Atomicity)
指事務內所有操作要么一起執行成功,要么都一起失敗(或者說是回滾);如事務經典轉賬案例:A給B轉賬,A把錢扣了,但B沒有收到;可見這種錯誤是不能接受的,最終會回滾,這也是原子性的重要性。
* 一致性(Consistency)
指事務執行前后的狀態一致,如事務經典轉賬案例:A給B互相轉賬,不管怎么轉,最終兩者錢的總和還是不變;
* 持久性(Durability)
指事務一旦提交,數據就已經永久保存了,不能再回滾;
* 隔離性(Isolation)
指多個并發事務之間的操作互不干擾,但是事務的并發可能會導致數據臟讀、不可重復讀、幻讀問題,根據業務情況,采用事務隔離級別進行對應數據讀問題處理。
##### 1.3 事務隔離級別
* 讀未提交(**Read uncommitted**)
指一個事務讀取到其他未提交事務的數據。可能導致數據**臟讀**。
轉賬案例:A正在給B轉賬,本來轉的1000,A多輸入了個0,變成10000,但此事務還未提交,但此時B查詢到轉入的是10000,但A取消事務回滾之后,B又查詢不到轉入的數據。這種情況就是**臟讀**
* 讀已提交(**Read committed**)
指一個事務只能讀取到其他事務已提交的數據,從而解決了**臟讀**的問題。但可能導致數據**不可重復讀**;
轉賬案例:A要給B轉賬1000,A先查看了一下余額,有1000,然后開始給B轉錢,但此時A家里電費通過開啟的自動繳費功能,自動從A賬戶扣除200繳納電費,并提交;當A轉賬準備提交,再次確認余額時,錢少了200。這樣就導致同一個事務中多次查詢的結果不一致,這種情況就是**不可重復讀**;
* 可重復讀(**Repeatable read**)
指事務只要一開啟,就不允許其他事務進行修改操作,從而解決了**不可重復讀**問題。但可能導致數據**幻讀**;
轉賬案例:A經常給B轉賬,到年底了,需要查賬,然后開啟了一個事務進行查詢統計,剛開始查詢只是10條轉賬記錄,正準備統計時,因為緊急情況A需要給B轉一筆錢應急,從而**新增**了一條新記錄,并提交;而查賬事務正在統計中,最后發現轉賬額和看到的10條轉賬記錄不匹配。這種情況就是**幻讀**
* 序列化(**Serializable**)
指事務之間只能串行話執行,就像隊列一樣,排隊進行,這樣就解決了**幻讀**的問題,但是這種級別的并發性能不高,非特殊需求,這種級別一般不用。
#### 2\. 分布式事務場景
一個項目對應一個數據庫,這種單機業務是平時處理的比較多的;這里主要歸納一下會出現分布式事務的場景。
##### 2.1 一個項目多個數據庫

這種情況一般是并發量不大,但數據量比較大的情況,就比如一些采集設備數據做實時分析的系統,如傳感器數據、電機狀態等,經過一段時間,數據量會很多,導致單個數據庫效率變低,所以通常會采用分業務存儲。
如上圖,如果出現需要操作DB1中數據的同時又需要操作DB2數據,確保兩次操作要么都成功,要么都失敗,這就需要事務,而這種和單一系統(一個項目,一個數據庫)的事務處理方式不一樣,得分布式事務進行處理。
##### 2.2 多個項目一個數據庫

有些系統需要將業務分開開發和部署,便于代碼管理和后期維護,在數據庫資源允許的情況下可以共用一個數據庫,在這種情況下如果有事務操作,同樣需要分布式事務進行處理。
##### 2.3 多個項目多個數據庫

這種方式其實就是微服務模式,分業務劃分項目,每個業務對應一個數據庫,這種場景下項目之間的事務肯定是分布式的啦
#### 3\. CAP了解
##### 3.1 簡介
對于分布式應用場景,有很多因素是不可控的,如網絡不通、設備宕機、自然災害等原因導致服務不可用,這種情況對于分布式而言需要有一定的取舍,不能因為個別服務的不可用,導致整個系統崩掉。通常CAP理論會成為分布式指標的取舍,根據系統業務需求,滿足其中兩個指標即可。如下圖:

**CAP是Consistency(一致性)、Availability(可用性)、PartitionTolerance(分區容錯性)三個詞的縮寫**,具體含義如下:
* **C(Consistency-一致性):是指在寫操作之后,任意節點進行讀取時,都能一致獲取到最新的數據狀態**。為了保證數據一致性,在同步數據時會對資源短時進行鎖定,目的為了避免獲取到老的數據,導致數據不一致情況,但這樣就會導致服務在短時間內不可用。
* **A(Availability-可用性):是指發起任何操作時都可以得到響應結果,不會出現響應超時或響應錯誤**。就算是數據在同步過程中也要保證可用,即寧可拿到舊數據也不要報錯。
* **P(PartitionTolerance-分區容錯性):這里的分區是指網絡分區**,通常分布式系統,各節點會部署到不同子網,由于網絡具有不可控性,可能會導致節點之間的通信失敗;但在設計此類系統時,應該考慮這種情況,保證提供正常的服務,這其實可以理解為平時咱們說的高可用;**這個指標是分布式系統必備的,不然就不能叫高可用系統啦**。
##### 3.2 CAP組合
其實通過上面的概述,**C(一致性)和A(可用性)是互相排斥的**,為了保證一致性,會鎖定資源導致短時間不可用,而可用性的要求就是必須對操作有對應的響應結果,就算得到的數據不是最新的也行,目的是保證可用。**而P(分區容錯性)是分布式系統中必備指標,所以在分布式系統中經常的組合就是CP和AP**。
* **CP:放棄可用性,注重一致性和分區容錯性,其實這就是所謂的強一致性**,可能在銀行跨行轉賬這種強一致業務場景才會用到,具體得根據業務場景做取舍。
* **AP:放棄強一致性,注重可用性和分區容錯性**,這是現在絕大多數分布式業務場景的選擇,只要最后能保證最終一致性(Base理論)即可。
##### 3.3 簡單理解一下BASE理論
**BASE是Basically Available(基本可用),Soft State(軟狀態)和Eventually Consistent(最終一致性)三個短語的縮寫,是對AP的一種擴展,即當出現故障時允許部分服務不可用,但要保證核心服務正常。對于數據,允許一定時間內不一致,通過中間狀態(軟狀態)過渡,最后保證最終一致即可**。
舉例說明:
**Basically Available(基本可用)**:比如一個系統注冊用戶成功時需要發送信息通知,允許發送信息不成功,但注冊這個核心功能要保證可用。
**Soft State(軟狀態)**:平時見得最多的軟狀態有:“支付中”、“數據處理中”等,這些狀態是為了滿足可用性和最終一致增加的過渡狀態。
**Eventually Consistent(最終一致性)**:比如在購買商品時,支付的過程中會顯示“支付中”,最終會顯示“支付成功”,這個時候其實就保證最終你的賬戶和收款賬戶這個事務最終一致了,這種事務可以理解為“**柔性事務**”。
#### 4\. 分布式事務常用的解決方案
* **2PC(Two-phase commit protocol)**,又稱二階段提交,是一種強一致性解決方案。對其進行補充的還有一個叫**3PC**的解決方案。
* **TCC(Try Confirm ?Cancel)**,補償事務。
* **本地消息表**
* **消息事務**
* **最大努力通知**
這里先不細說,后續逐個擊破,最終還是要用代碼落地。
### 總結
這篇只是一個開端,主要是大概回顧一下分布式事務中常遇到的知識點,后續主要是針對各個解決方案的落地,一起擼碼。
一個被程序搞丑的帥小伙,關注"Code綜藝圈",和我一起學~~~

圖片
收錄于話題#微服務那些事
15個
下一篇gRPC四種模式、認證和授權實戰演示
文章已于2021/07/23修改
喜歡此內容的人還喜歡
[
gRPC趁現在還沒大火,搶先了解一下
gRPC趁現在還沒大火,搶先了解一下
...
Code綜藝圈
不喜歡
不看的原因
確定
* 內容質量低
* 不看此公眾號
](javascript:void(0);)[
gRPC四種模式、認證和授權實戰演示
gRPC四種模式、認證和授權實戰演示
...
Code綜藝圈
不喜歡
不看的原因
確定
* 內容質量低
* 不看此公眾號
](javascript:void(0);)[
Redis 帝國的神秘使者,竟然想改造 C 語言!
Redis 帝國的神秘使者,竟然想改造 C 語言!
...
悟空聊架構
不喜歡
不看的原因
確定
* 內容質量低
* 不看此公眾號
](javascript:void(0);)

微信掃一掃
關注該公眾號
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南