当前位置:网站首页>Analysis of distributed transaction solution Seata golang
Analysis of distributed transaction solution Seata golang
2022-06-28 04:48:00 【May Hacker】
List of articles
Preface
Seata It's easy to use , High performance 、 Open source one stop distributed transaction solution , Open source by Alibaba .
2020 year 4 month , Liuxiaomin started to base on Seata Start multilingual golang project , After a year of development ,seata-golang Released 1.0.0 edition .
Seata framework

● TC:Transaction coordinator, It's a distributed transaction coordinator .
● TM:Transaction manager, It's a transaction manager , Responsible for opening global transactions 、 Commit and roll back .
● RM:Resource Manager, It manages branch transaction resources , After it joins the global transaction group , towards TC Report the execution status of branch transactions .
● XID:TM When opening a global transaction , Will be in TC Create a GlobalSession,GlobalSession The globally unique ID of is XID.
● BranchID:RM towards TC After registering branch transactions , stay TC The side generates a BranchSession,BranchID Globally unique identification of this BranchSession.
When RM towards TC When reporting branch execution failure ,TC Will mark this BranchSession The status of is failure , then TM When a rollback is initiated ,TC according to XID Find all successfully executed transaction branches , Tell them to roll back .
The following is a complete process for ordering and purchasing 
The user sends an order placing request to the aggregation layer
- Polymeric layer TM towards TC Request to start a global transaction ,TC establish
GlobalSession, A session representing a global transaction - TC Back to the aggregation layer TM One Xid, Used to mark this global transaction , Then the polymerization layer TM To obtain the Xid To order service and inventory service respectively
- Order service to TC Registration transaction branch ,TC Will create a
BranchSession, And added to the global transaction - TC Return to the order service BranchId, Used to uniquely represent this branch transaction
- Inventory service to TC Registration transaction branch ,TC Will create a
BranchSession, And added to the global transaction - TC Return to the inventory service
BranchId, Used to uniquely represent this branch transaction - If the inventory service fails to execute the local logic , Will send to TC The report , launch
BranchReportRequest; And will return err to TM, - TM After perceiving that the inventory service local branch transaction execution fails ,TM Will send to TC Initiate a global rollback , namely
GlobalRollbackRequest - TC Consider the global transaction failed , Notify the... Of each service RM, Give Way RM Initiate rollback at the local transaction branch
Refer to the... Involved in the above process seata Methods are abstracted :
You can ignore SAGA Pattern ,seata-golang Not implemented in 
Seata Golang Supported patterns
Seata-Golang Support AT and TCC Two modes .
In a nutshell :
AT Depending on the local database transaction characteristics , Including rollback 、 Submission, etc
TCC The pattern relies on the user-defined implementation to rollback and commit transactions , Abstract out three methods :Try、Confirm、Cancel, That's why it's called TCC
AT Pattern
AT The rollback of the pattern depends on the compensation for the operation performed ,seata-golang be based on TIDB Of Parser To identify what the user has done , Constructed as Undo Log Then rollback compensation is performed for these operations .
TCC Pattern
Rely on developers to implement seata Of TCC Interface , That is, customize Try、Confirm、Cancel Methods
There are many constraints on developers
Seata Source analyses
1.TC Global transaction coordinator
type TransactionCoordinator struct {
sync.Mutex
maxCommitRetryTimeout int64
maxRollbackRetryTimeout int64
rollbackDeadSeconds int64
rollbackRetryTimeoutUnlockEnable bool
asyncCommittingRetryPeriod time.Duration
committingRetryPeriod time.Duration
rollingBackRetryPeriod time.Duration
timeoutRetryPeriod time.Duration
streamMessageTimeout time.Duration
holder holder.SessionHolderInterface
resourceDataLocker lock.LockManagerInterface
locker GlobalSessionLocker
idGenerator *atomic.Uint64
futures *sync.Map
activeApplications *sync.Map
callBackMessages *sync.Map
}
Begin() Method to start a global transaction
func (tc *TransactionCoordinator) Begin(ctx context.Context, request *apis.GlobalBeginRequest) (*apis.GlobalBeginResponse, error) {
// Generate XID
transactionID := uuid.NextID()
xid := common.GenerateXID(request.Addressing, transactionID)
// Global transaction
gt := model.GlobalTransaction{
// The global session
GlobalSession: &apis.GlobalSession{
Addressing: request.Addressing,
XID: xid,
TransactionID: transactionID,
TransactionName: request.TransactionName,
Timeout: request.Timeout,
},
}
// Open global transaction , In fact, the state of the global transaction is modified
gt.Begin()
// Add global transactions to holder in
err := tc.holder.AddGlobalSession(gt.GlobalSession)
if err != nil {
return &apis.GlobalBeginResponse{
ResultCode: apis.ResultCodeFailed,
ExceptionCode: apis.BeginFailed,
Message: err.Error(),
}, nil
}
// Start the coroutines , Receive global transaction events
runtime.GoWithRecover(func() {
evt := event.NewGlobalTransactionEvent(gt.TransactionID, event.RoleTC, gt.TransactionName, gt.BeginTime, 0, gt.Status)
event.EventBus.GlobalTransactionEventChannel <- evt
}, nil)
log.Infof("successfully begin global transaction xid = {}", gt.XID)
return &apis.GlobalBeginResponse{
ResultCode: apis.ResultCodeSuccess,
XID: xid,
}, nil
}
TC The global transaction coordinator has three concepts
1.1 LockManager
AT In mode , Lock the data on the branch transaction to TC On , Ensure the isolation of transaction data 
1.2 SessionManager
management BranchSession, Record transaction execution status 、 Persistent transaction data
Now there are two ways to do it :
- FileBasedSessionManager: The transaction data is saved to memory , And persist to local files
- DBBasedSessionManager: The transaction data is persisted to the database , In this way ,TC High availability
You may consider ETCD Or right TC do Raft, It is the issue that the follow-up community will consider .
1.3 Transaction Manager
namely TM, Transaction manager , We'll talk about that
2.TM Transaction manager
According to the previous description ,TM Responsible for some global operations , Including the request TC Open global transaction 、 Global commit 、 Global rollback and other operations
type TransactionManagerInterface interface {
// GlobalStatus_Begin a new global transaction.
Begin(ctx context.Context, name string, timeout int32) (string, error)
// Global commit.
Commit(ctx context.Context, xid string) (apis.GlobalSession_GlobalStatus, error)
// Global rollback.
Rollback(ctx context.Context, xid string) (apis.GlobalSession_GlobalStatus, error)
// Get current status of the give transaction.
GetStatus(ctx context.Context, xid string) (apis.GlobalSession_GlobalStatus, error)
// Global report.
GlobalReport(ctx context.Context, xid string, globalStatus apis.GlobalSession_GlobalStatus) (apis.GlobalSession_GlobalStatus, error)
}
It is worth noting that ,TransactionManagerInterface The method in , It's a notice TC Do the corresponding operation
With Rollback Methods as an example , The concrete implementation is the request TC Roll back global transactions ,TC We'll inform everyone RM Rollback the local branch transaction .
func (manager *TransactionManager) Rollback(ctx context.Context, xid string) (apis.GlobalSession_GlobalStatus, error) {
// RPC request TC, Let it roll back the global transaction
request := &apis.GlobalRollbackRequest{
XID: xid}
resp, err := manager.rpcClient.Rollback(ctx, request)
if err != nil {
return 0, err
}
if resp.ResultCode == apis.ResultCodeSuccess {
return resp.GlobalStatus, nil
}
return 0, &exception.TransactionException{
Code: resp.GetExceptionCode(),
Message: resp.GetMessage(),
}
}
3.RM Explorer
RM Mainly responsible for the management of local branch affairs
type ResourceManagerInterface interface {
BranchCommit(ctx context.Context, request *apis.BranchCommitRequest) (*apis.BranchCommitResponse, error)
BranchRollback(ctx context.Context, request *apis.BranchRollbackRequest) (*apis.BranchRollbackResponse, error)
// RegisterResource Register a Resource to be managed by Resource Manager.
RegisterResource(resource model.Resource)
// UnregisterResource Unregister a Resource from the Resource Manager.
UnregisterResource(resource model.Resource)
// GetBranchType ...
GetBranchType() apis.BranchSession_BranchType
}
besides ,RM It is also responsible for starting the global transaction , towards TC Registration transaction branch , therefore seata-golang Extract three notifications TC The interface of
type ResourceManagerOutbound interface {
// BranchRegister towards TC Registration transaction branch
BranchRegister(ctx context.Context, xid string, resourceID string, branchType apis.BranchSession_BranchType,
applicationData []byte, lockKeys string) (int64, error)
// BranchReport Report the execution status of branch transactions
BranchReport(ctx context.Context, xid string, branchID int64, branchType apis.BranchSession_BranchType,
status apis.BranchSession_BranchStatus, applicationData []byte) error
// LockQuery lock resource by lockKeys.
LockQuery(ctx context.Context, xid string, resourceID string, branchType apis.BranchSession_BranchType, lockKeys string) (bool, error)
}
边栏推荐
- Recommended by Alibaba P8, Fiddler packet capturing tool (I)
- Mask's miserable and inspirational childhood, who is introverted by campus violence
- A queue of two stacks
- UI automation test framework construction - write an app automation
- The growth summer challenge is coming | learn and create two major tracks, and start the tutor registration!
- UI自動化測試框架搭建 —— 編寫一個APP自動化
- Audio and video technology development weekly
- CUPTI error: CUPTI could not be loaded or symbol could not be found.
- [NOIP2002 普及组] 过河卒
- 测试/开发程序员真的是青春饭吗?世界是公平的,咱们都凭实力说话......
猜你喜欢

How do I get the STW (pause) time of a GC (garbage collector)?

Role of native keyword

Matlab exercises -- exercises related to symbolic operation

One article explains in detail | those things about growth

mysql修改密码报错需要怎么做

灵活的IP网络测试工具——— X-Launch

2022年中国音频市场年度综合分析

Idle interrupt cannot be cleared

first. Net core MVC project

Excel knowledge and skills summary
随机推荐
知识点滴 - 关于汉语学习的网络资源
Password encryption MD5 and salt treatment
Analyse complète annuelle du marché chinois de l'audio en 2022
leetcode:714. The best time to buy and sell stocks includes handling fee [DP dual status]
代码理解:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION
Simple factory mode
一文详解|增长那些事儿
Performance optimization and implementation of video codec
Multi thread implementation rewrites run (), how to inject and use mapper file to operate database
27年,微软IE结束了!
C语言全局变量(c文件和h文件中的全局变量、静态全局变量)使用注意事项
Go语言学习教程(十四)
2022年中国音频市场年度综合分析
CDC全量抽取mysql数据时,怎么才能加快ChunkSplitter呢?
Go language -select statement
Go language learning tutorial (14)
Multithreading and high concurrency V: detailed explanation of wait queue, executor and thread pool (key)
成长一夏 挑战赛来袭 | 学习、创作两大赛道,开启导师报名啦!
Component splitting practice
灵活的IP网络测试工具——— X-Launch