Community Blog Go MySQL Driver Integrates Seata-Golang to Solve Distributed Transactions

Go MySQL Driver Integrates Seata-Golang to Solve Distributed Transactions

This article explores the relationship between MySQL Driver and Seata-Golang.

By Liu Xiaomin



In April 2020, we began trying to implement a Seata-Golang distributed transaction framework based on the Go language. The Seata AT has no business code intrusion and is highly praised by developers. The Seata AT for Java provides a proxy for the data source. During the execution of SQL statements, it intercepts and parses the SQL statements to obtain the copies of the corresponding data in the database before and after the execution. After serialization, the copies will be saved and be used for rolling back corresponding data when coordinating the rollback by the transaction coordinator (TC). When implementing the client-go Seata AT, the primary consideration is how to be more friendly to business developers and to minimize intrusions.


When using the Go language to operate the database, the official library of the Go language database/sql will be supplied, and a data source operation object db will be obtained through sql.Open("mysql", ${dsn}). When opening a transaction, use db.Begin() or db.BeginTx(ctx, &sql.TxOptions{}) to obtain the transaction operation object tx and execute SQL query using tx.Query. Execute SQL operations, such as add, modify, and delete by tx.Exec. Finally, use tx.Commit() to submit or use tx.Rollback() to roll back.

The Go language official library database/sql provides a standard abstraction layer that allows developers to manipulate different databases by implementing a set of standard abstraction APIs for different drivers. Developing a Go-version Seata AT must be compatible with database/sql. Through researching APIs in database/sql, data source operation objects are created. Database-related configurations must be passed in through the data source name (DSN) abstractly. The following is the definition of DSN:


The implementation of Seata AT for the data source proxy requires interaction with the TC. If Seata AT is implemented on the driver layer, some parameters for interaction with TC must be passed to the driver layer through DSN, which damages the design somewhat. Therefore, a compromise plan was adopted by implementing Seata AT on the database/sql layer to proxy the data source operation objects created by database/sql. Data source proxy object implements the tx interfaces defined by the database/sql library and provides another method to start a transaction: Begin(). Although the method is not fully compatible with the APIs in database/sql, the key interfaces are the same as their definition. At this point, the development of the core features of the Seata-Golang project has been completed.

type Tx interface {
    Commit() error
    Rollback() error


Seata-Golang was gradually understood and trialed by some developers after making it open-source. The community also heard some feedback about it. Many developers are not used to writing native SQL and want Seata-Golang to integrate into the ORM framework. The design at that time was not fully compatible with database/sql. As a result, there were some difficulties during the integration. Thanks to some previous research on the driver and the enthusiastic call of developers in the community, there was a sudden inspiration burst in March 2021. Why must parameters be transmitted through DSN? After initializing the Seata-Golang client, just use the API config.GetATConfig() on the client to get it directly when needed.


Therefore, after two weeks of development, the first fully database/sql compatible MySQL driver with Seata-Golang integration was developed. The project is open-source on GitHub, which is in the beta state currently. Examples can be used on GitHub to view and test the usage.

Some Details of Driver

  • When using this driver for distributed transactions, developers cannot set the interpolateParams as true in the DSN.

This involves the text protocol and binary protocol of MySQL. For the differences between the two protocols, please see the references at the end of this article. The driver only processes the binary protocol. When interpolateParams is enabled, SQL statements are executed by the text protocol.

  • When using this driver for interaction with tc after being added to a global transaction group, developers need to use db.BeginTx(ctx context.Context, opts driver.TxOptions) and add the value of the global transaction identity of XID in ctx.
ctx := context.WithValue(context.Background(), mysql.XID, c.Request.Header.Get("XID"))
tx, err := dao.BeginTx(ctx, &sql.TxOptions{
        Isolation: sql.LevelDefault,
        ReadOnly:  false,

XID is passed to the driver layer and saved in the connection objects in &mysqlConn. It is used when interacting with TC.

  • Developers must initialize the Seata-Golang client and MySQL driver first when using this driver for distributed transactions:

Please see seata -go-samples for details


This project has reached its one year anniversary since the launch of v0.1.0 in Jul 10, 2020.. With the MySQL driver in this article, we hope to lower the threshold and make it more practical for everyone. Developers do not have to worry that Go does not have a distributed transaction processing solution when selecting a microservice development technology stack. In addition, this project is very young, and there are still many areas that need to be improved. If you are interested, please participate in the community to help improve it!


Liu Xiaomin (GitHubID: dk-lockdown) is currently working in the H3C Chengdu branch. He is good at Java and the Go language and works with cloud-native and microservice-related technologies. He specializes in distributed transactions.


0 0 0
Share on

You may also like


Related Products