Seata 是一款開源的分散式事務解決方案,致力於提供高效能和簡單易用的分散式事務服務。Seata 將為使用者提供了 AT、TCC、SAGA 和 XA 事務模式,為使用者打造一站式的分散式解決方案。
在 Seata 開源之前,Seata 對應的內部版本在阿里經濟體內部一直扮演著分散式一致性中介軟體的角色,幫助經濟體平穩地度過歷年的雙 11,對各 BU 業務進行了有力的支撐。經過多年沉澱與積累,商業化產品先後在阿里雲、金融雲進行售賣。2019 年 1 月為了打造更加完善的技術生態和普惠技術成果,Seata 正式宣佈對外開源,未來 Seata 將以社群共建的形式幫助其技術更加可靠與完備。
TC (Transaction Coordinator) - 事務協調者
維護全域性和分支事務的狀態,驅動全域性事務提交或回滾。
TM (Transaction Manager) - 事務管理器
定義全域性事務的範圍:開始全域性事務、提交或回滾全域性事務。
管理分支事務處理的資源,與 TC 交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。
Seata 提供了 XA、AT、TCC 與 SAGA 四種分散式事務模式
https://seata.io/zh-cn/docs/dev/mode/xa-mode
前提:
整體機制:
在 Seata 定義的分散式事務框架內,利用事務資源(資料庫、訊息服務等)對 XA 協定的支援,以 XA 協定的機制來管理分支事務的一種 事務模式。
問題:
https://seata.io/zh-cn/docs/dev/mode/at-mode
前提:
整體機制:
兩階段提交協定的演變:
問題:
https://seata.io/zh-cn/docs/dev/mode/tcc-mode
AT 模式基於 支援本地 ACID 事務 的 關係型資料庫:
相應的,TCC 模式,不依賴於底層資料資源的事務支援:
所謂 TCC 模式,是指支援把 自定義 的分支事務納入到全域性事務的管理中。
TCC,Try Confirm/Cancel,同樣也是 2PC 的,其與 AT 的重要區別是,支援將自定義的分支事務納入到全域性事務管理中,即可以實現客製化化的紀錄檔清理與回滾過程。當然,該模式對業務邏輯的侵入性是較大的。
https://seata.io/zh-cn/docs/dev/mode/saga-mode
對於架構複雜,且業務流程較多較長的系統,一般不適合使用 2PC 的分散式事務模式。因為這種系統一般無法提供 TM、TC、RM 三種介面。此時,我們可以嘗試著選擇 Saga 模式
Saga 模式是 SEATA 提供的長事務解決方案,在 Saga 模式中,業務流程中每個參與者都提交本地事務,當出現某一個參與者失敗則補償前面已經成功的參與者,一階段正向服務和二階段補償服務都由業務開發實現。
其應用場景是:在無法提供 TC、TM、RM 介面的情況下,對於一個流程很長的複雜業務,其會包含很多的子流程(事務)。每個子流程都讓它們真實提交它們真正的執行結果。
只有當前子流程執行成功後才能執行下一個子流程。若整個流程中所有子流程全部執行成功,則整個業務流程成功;只要有一個子流程執行失敗,則可採用兩種補償方式:
與 2PC 模式的區別
Saga 模式的所有分支事務是序列執行的,而 2PC 的則是並行執行的。
Saga 模式沒有 TC,其是通過子流程間的訊息傳遞來完成全域性事務管理的,而 2PC 則具有 TC,其是通過 TC 完成全域性事務管理的。
無論是 AT 模式,還是 TCC 模式或 XA 模式,都需要有事務協調器 TC,即 Seata Server
下載地址:https://seata.io/zh-cn/docs/download
Seata 的原始碼包與二進位制包均需要下載。因為 Seata Client 需要使用 Seata 的原始碼包中的一個 sql 指令碼檔案。
Seata Server 需要對全域性事務與分支事務進行儲存,以便對它們進行管理。其儲存模式目前支援三種:file、db 與 redis。
將 seata-server-1.7.1.zip 解壓後,修改 seata 解壓目錄下的 conf 目錄中的 application.yml檔案。預設file模式,在該檔案中需要設定三類資訊:Seata 的設定中心、Seata 的註冊中心,及回滾紀錄檔資訊。不過,對於 file 模式,只需要修改以下位置即可。
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: file
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: file
store:
# support: file 、 db 、 redis
mode: file
在 seata/bin
目錄下直接雙擊 seata-server.sh
批次檔即可啟動。啟動後在該 bin 目錄中就可以直接看到生成的 sessionStore 目錄及其中的 root.data 檔案。
file 模式一般用於簡單測試,生產環境下使用的是 db 模式
在 seata 包解壓目錄的 script/server/db
下找到 mysql.sql
檔案。該指令碼檔案中建立了 4張表。這 4 張表都是用於儲存整個系統中分散式事務相關紀錄檔資料的。
該指令碼檔案中僅有建表語句,沒有建立資料庫的語句,說明使用什麼資料庫名稱都可以。為了方便,我們在指令碼檔案中直接新增了建庫語句,並指定資料庫名稱為 seata。
create database if not exists seata;
修改 seata 解壓目錄下的conf
目錄中的 application.yml
檔案。在該檔案中需要設定三類資訊:Seata 的設定中心、Seata 的註冊中心,及回滾紀錄檔資訊。
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${log.home:${user.home}/logs/seata}
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash
console:
user:
username: seata
password: seata
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username: nacos
password: nacos
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
data-id: seataServer.properties
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username: nacos
password: nacos
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
user: root
password: 123456
min-conn: 10
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 1000
max-wait: 5000
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login
mysql5.7 使用 com.mysql.jdbc.Driver
Mysql8.0 使用 com.mysql.cj.jdbc.Driver
修改 seata 解壓目錄的script/config-center
下的 config.txt
檔案。這裡的內容都是 key-value,將來都是作為 nacos 設定中心中的資料出現的,將來開啟 nacos 可以根據其 key 逐條檢視到
指定這裡要使用的儲存模式為 db
將 store.mode
、store.lock.mode
、store.session.mode
中原來的 file 值修改為 db。再將公鑰行註釋掉。
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
由於這裡指定的儲存模式是db,所以需要將file模式與redis模式相關的設定全部刪除。
在 Nacos 設定中心定義 seataServer.properties 檔案。該檔案是在上述 application.yml 中指定的 data-id 檔案。將前面修改後的 config.txt 檔案內容全部複製到 seataServer.properties檔案中。
#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none
#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
#Transaction rule configuration, only for the client
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h
#Log rule configuration, for client and server
log.exceptionRate=100
#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=db
store.lock.mode=db
store.session.mode=db
#Used for password encryption
#store.publicKey=
#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
#Transaction rule configuration, only for the server
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false
#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
在 seata 解壓目錄下的 bin 目錄中有個檔案 seata-server.sh
,在命令列執行這個批次檔
./seata-server.sh -m db
在 nacos 中可以看到 seata-server 的服務時,表示 seata 啟動成功了。
埠預設7091
、賬號密碼:seata
https://seata.io/zh-cn/docs/overview/faq
1.Seata 目前可以用於生產環境嗎?
2.Seata 目前支援高可用嗎?
3.undo_log表log_status=1的記錄是做什麼用的?
4.怎麼使用Seata框架,來保證事務的隔離性?
5.髒資料回滾失敗如何處理?
6.為什麼分支事務註冊時, 全域性事務狀態不是begin?
7.Nacos 作為 Seata 設定中心時,專案啟動報錯找不到服務。如何排查,如何處理?
8.Eureka做註冊中心,TC高可用時,如何在TC端覆蓋Eureka屬性?
9.java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.jsontype.TypeSerializer.typeId(Ljava/lang/Object;Lcom/fasterxml/jackson/core/JsonToken;)?
10.為什麼mybatis沒有返回自增ID?
11.io.seata.codec.protobuf.generated不存在,導致seata server啟動不了?
12.TC如何使用mysql8?
13.支援多主鍵?
14.使用HikariDataSource報錯如何解決 ?
15.是否可以不使用conf型別組態檔,直接將設定寫入application.properties?
16.如何自己修改原始碼後打包seata-server ?
17. Seata 支援哪些 RPC 框架 ?
18. java.lang.NoSuchMethodError: com.alibaba.druid.sql.ast.statement .SQLSelect.getFirstQueueBlockLcom/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock;
19. apache-dubbo 2.7.0出現NoSuchMethodError ?
20. 使用 AT 模式需要的注意事項有哪些 ?
21. win系統使用同步指令碼進行同步設定時為什麼屬性會多一個空行?
22. AT 模式和 Spring @Transactional 註解連用時需要注意什麼 ?
23. Spring boot 1.5.x 出現 jackson 相關 NoClassDefFoundException ?
24. SpringCloud xid無法傳遞 ?
25. 使用動態資料來源後的常見問題 ?
26. Could not found global transaction xid = %s, may be has finished.
27. TC報這個錯:An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception是什麼原因?
28. 資料庫開啟自動更新時間戳導致髒資料無法回滾?
29. 還沒到全域性事務超時時間就出現了timeoutrollcking?
30. Seata現階段支援的分庫分表解決方案?
31. Seata 使用註冊中心註冊的地址有什麼限制?
32. seata-server cannot be started due to Unrecognized VM option 'CMSParallelRemarkEnabled' Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.導致seata-server無法啟動?
33. Seata的SQL支援範圍?
34. Seata的JDK版本要求?
35. Oracle的NUMBER長度超過19之後,實體使用Long對映,導致獲取不到行資訊,導致undo_log無法插入,也無法回滾?
36. 怎麼處理 io.seata.rm.datasource.exec.LockConflictException: get global lock fail ?
37. 為什麼在使用者端在編譯和執行時 JDK 版本都是 1.8 的情況下還會出現 java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer 錯誤 ?
38. 為什麼在使用Apple的M1晶片下載maven依賴時,無法下載依賴com.google.protobuf:protoc:exe:3.3.0
?
39. 1.4.2及以下版本回滾時丟擲Cannot construct instance of java.time.LocalDateTime
40. Seata-Server 使用 DB 作為儲存模式時,有哪些注意事項?
41. Oracle使用timestamp欄位型別回滾失敗?
42. 丟擲異常後事務未回滾?
43. 怎麼處理@FeignClient註解url不起效,提示 Load balancer does not have available server for client錯誤?