×
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

1

Background

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.

2

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:

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

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
}

Transition

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.

3

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:
config.InitConf(configPath)
  client.NewRpcClient()
  mysql.InitDataResourceManager()
  mysql.RegisterResource(config.GetATConfig().DSN)

Please see seata -go-samples for details

Message

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!

Author

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.

References

0 0 0
Share on

You may also like

Comments

Related Products

  • PolarDB for MySQL

    Alibaba Cloud PolarDB for MySQL is a cloud-native relational database service 100% compatible with MySQL.

    Learn More
  • Database for FinTech Solution

    Leverage cloud-native database solutions dedicated for FinTech.

    Learn More
  • Lindorm

    Lindorm is an elastic cloud-native database service that supports multiple data models. It is capable of processing various types of data and is compatible with multiple database engine, such as Apache HBase®, Apache Cassandra®, and OpenTSDB.

    Learn More
  • Oracle Database Migration Solution

    Migrate your legacy Oracle databases to Alibaba Cloud to save on long-term costs and take advantage of improved scalability, reliability, robust security, high performance, and cloud-native features.

    Learn More