穀粒商城高階篇—分散式事務
分散式事務
本地事務:在分散式系統只能控制住自己的回滾,控制不了其他服務的回滾
分散式事務:最大原因——網路問題
本地事務
1、事務基本性質
- 原子性 Atomicity 同成功、同失敗
- 一致性 Consistency 整體一致
- 隔離性 Isolation 事務之間相互隔離
- 永續性 Durablility 事務成功,資料一定入庫
2、事務的隔離級別
- READ UNCOMMITTED 讀未提交,髒讀
- READ COMMITTED 讀已提交,不可重複讀
- REPEATABLE_READ 可重複讀 mysql預設,幻讀,mysql的InnoDB通過next-key locks機制避免幻讀
- SERIALIZABLE 序列號
3、事務的傳播行為
- PROPAGATION_REQUIRE,存在就加入,沒有就建立
- PROPAGATION_SUPPORTS,存在就加入,沒有就非事務
- PROPAGATION_MANDATORY,存在就加入,不存在拋異常
- PROPAGATION_REQUIRE_NEW,建立新事務
- PROPAGATION_NOT_SUPPORT,存在就掛起,沒有就非事務
- PROPAGATION_NEVER,存在就拋異常,沒有就非事務
- PROPAGATION_NESTED,存在就巢狀,沒有就建立
4、SpringBoot 事務
@Transactional //注意:事務使用代理物件控制的,同一個物件內事務方法預設失效,原因是繞過了代理物件
解決:使用代理物件來呼叫事務方法
1、引入aop依賴,引入了aspectj
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version></version>
</dependency>
2、@EnableAspectJAutoProxy(exposeProxy = true);開啟 aspectj動態代理功能,以後所有動態代理都是aspectj建立的(沒有介面也可以建立動態代理)。
3、用代理物件互調
@Transaction(timeout = 30)
public void a(){
OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();
orderService.b();
orderService.c();
int i = 10/2;
}
@Transaction(propagation = Propagation.REQUIRED,timeout = 2)
public void b(){
}
@Transaction(propagation = Propagation.REQUIRED_NEW,timeout = 20)
public void c(){
}
分散式事務
1、為什麼有分散式事務
分散式系統:機器宕機、網路異常、訊息丟失、訊息亂序、資料錯誤、不可靠TCP、儲存資料丟失...
2、CAP定理與BASE理論
-
CAP定理
- 一致性Consistency
- 可用性Availability
- 分割槽容錯性Partition tolerance
永遠滿足分割槽容錯,一致性和可用性二選一
分散式系統中一致性演算法:raft(領導選舉、日誌複製)、paxos
-
面列的問題
保證P和A,捨棄C
-
BASE理論
無法做到強一致性,保證最終一致性
- 基本可用 Basically Abailable
- 軟狀態 Soft State
- 最終一致性 Eventual Consistency
3、分散式事務集中解決方案
-
2PC模式
二階提交:
第一階段:事務協調器要求每個設計事務的資料庫預提交此操作,並反應是否可以提交
第二階段:事務協調器要求每個資料庫提交資料
其中,任何一個否決,所有資料庫回滾事務中的資訊。
協議簡單,商業資料庫成本低
效能不理想,無法滿足高併發
-
柔性事務-TCC事務補償型方案
-
柔性事務-最大努力通知
按規律進行通知,不保證一定通知成功,但會提供可查詢操作介面進行核對。
用在與第三方系統通訊時。
結合MQ實現。
-
柔性事務-可靠訊息+最終一致性方案(非同步確保型)
業務事務提交之前,向實時訊息服務請求傳送訊息,試試訊息服務只紀律訊息,不真正傳送,事務提交後,確認傳送。
Seata
開源分散式事務解決方案,提供AT、TCC、SAGA、XA事務模式
TC 事務協調者
TM 事務管理器
RM 資源管理器
AT模式,需要建立UNDO_LOG表,用與回滾
-
每個服務建立UNDO_LOG表
-
安裝TC: seata-server
-
整合
-
匯入依賴
<!--在common裡匯入seata--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency>
-
啟動seata伺服器 seata-server(修改配置檔案 conf/registry.conf檔案)
-
所有用到分散式事務的微服務使用 seata DatasourceProxy代理自己的資料來源
-
每個微服務匯入 registry.conf file.conf
-
啟動測試
-
給分散式大事務的入口標註 @GlobalTransactional
-
每個遠端呼叫的小事務用@Transactional
預設 AT 模式,二階段(第一階段提交,二階段可通過日誌反向補償進行回滾)
seata不適合高併發,適合不用高併發場景事務方法。
-