Integrating Seata‑Golang AT and TCC Modes into Go Microservices
This guide explains how to embed Seata‑Golang’s AT and TCC distributed‑transaction modes into Go microservices, covering global transaction proxy creation, XID propagation via HTTP, Dubbo and gRPC, branch transaction handling, and the required code interfaces and implementations.
Seata‑Golang is a distributed‑transaction framework that supports AT (Automatic Transaction) and TCC (Try‑Confirm‑Cancel) modes. AT mode introduces less code intrusion than TCC but holds a global lock on the transaction coordinator, while TCC offers better performance by avoiding the lock.
1. Global Transaction Proxy
In Java, Seata scans methods annotated with @GlobalTransactional to generate AOP proxies. Go, being compiled, uses reflection: objects that need to be proxied must implement the GlobalTransactionProxyService interface.
type GlobalTransactionProxyService interface {
GetProxyService() interface{}
GetMethodTransactionInfo(methodName string) *TransactionInfo
}For the sample aggregation_svc, a proxy struct embeds the original service and declares an empty method CreateSo that Seata‑Golang will fill at runtime.
type ProxyService struct {
*Svc
CreateSo func(ctx context.Context, rollback bool) error
}Developers call tm.Implement(svc.ProxySvc); Seata‑Golang then creates the transaction metadata, executes the original CreateSo logic, and decides to commit or roll back based on the returned error.
2. Propagating the Global Transaction ID (XID)
Three transport mechanisms are demonstrated:
HTTP : The XID is set in the request header ( req.Header.Set("XID", rootContext.GetXID())) and retrieved downstream via c.Request.Header.Get("XID").
Dubbo : When using dubbo‑go, the XID is placed into the attachment map and passed through the RPC context.
context.WithValue(ctx, "attachment", map[string]string{"XID": rootContext.GetXID()})A custom SeataFilter extracts the XID from the attachment and injects it into the context for the downstream service.
type SeataFilter struct {}
func (sf *SeataFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
xid := invocation.AttachmentsByKey("XID", "")
if xid != "" {
return invoker.Invoke(context.WithValue(ctx, "XID", xid), invocation)
}
return invoker.Invoke(ctx, invocation)
}gRPC : The client adds the XID to outgoing metadata, and the server reads it from incoming metadata.
md := metadata.Pairs("XID", rootContext.GetXID())
ctx = metadata.NewOutgoingContext(context.Background(), md)Server side:
md, ok := metadata.FromIncomingContext(ctx)
// retrieve XID from md3. Branch Transaction Handling (AT Mode)
AT mode also requires a proxy for the data source. Seata parses SQL statements to capture before‑and‑after row images for rollback. Developers create a Seata‑compatible DB object by injecting their SQL driver:
db, err := exec.NewDB(config.GetATConfig(), yourSQLDriverInstance)If using an ORM such as XORM or GORM, extract the underlying driver and wrap it similarly, allowing both the ORM and Seata‑Golang to operate on the same connection.
To start a branch transaction, bind the received XID to a RootContext and call dao.Begin(ctx) to obtain a Tx object.
rootContext := &context.RootContext{Context: ctx}
rootContext.Bind("{XID from upstream}")
tx, err := dao.Begin(ctx)Execute SQL via tx.Exec(...), then commit or roll back with tx.Commit() or tx.Rollback(). The result is returned to the global transaction manager, which decides the fate of the whole transaction.
4. TCC Mode Integration
TCC requires implementing the TccService interface, whose methods receive a BusinessActionContext. The framework calls Try first; if all branches succeed, it automatically invokes Confirm for commit, otherwise Cancel for rollback.
type TccService interface {
Try(ctx *context.BusinessActionContext) (bool, error)
Confirm(ctx *context.BusinessActionContext) bool
Cancel(ctx *context.BusinessActionContext) bool
}Developers also create a proxy implementing TccProxyService and register it with tcc.ImplementTCC(proxyInstance). Sample code resides in the samples/tcc directory.
5. References
Seata official site: https://seata.io
Seata Java repository: https://github.com/seata/seata
Seata‑Golang project: https://github.com/opentrx/seata-golang
Dubbo‑go Seata example: https://github.com/dubbo-go-seata (link mentioned in text)
The article concludes that Seata‑Golang is fully compatible with the latest Seata Java 1.4 protocol, making it suitable for mixed Java‑Go stacks that need reliable distributed‑transaction support.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Native
We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
