Seata-go Quick Start
June 6, 2026 · View on GitHub
Prerequisites
- Go >= 1.20
- Java >= 8
- MySQL >= 8.0
Start Seata Server (Binary)
- Download the binary distribution from the official Seata-Server Release History page and extract it.
- Enter the extracted Seata Server directory.
- Start the server with
filestorage mode:
sh ./seata-server/bin/seata-server.sh -p 8091 -h 127.0.0.1 -m file
-p 8091: specifies the Seata Server port.-h 127.0.0.1: specifies the registry or advertised server address.-m file: stores transaction logs infilemode, which is suitable for a local quick start.
- Confirm that Seata Server is running and listening on
127.0.0.1:8091.
Start Seata Server (Docker)
- Pull the image from the official Docker Hub repository
apache/seata-server:
docker pull apache/seata-server:<seata-version>
- Start a container from the image you just pulled:
docker run --name seata-server \
-p 8091:8091 \
-e STORE_MODE=file \
apache/seata-server:<seata-version>
If local Docker has limited available memory and startup fails with
There is insufficient memory for the Java Runtime Environment to continueorCannot allocate memory, you can explicitly lower the JVM heap size, for example:docker run --name seata-server \ -p 8091:8091 \ -e STORE_MODE=file \ -e JVM_XMS=512m \ -e JVM_XMX=512m \ apache/seata-server:<seata-version>Add
-dif you want to run it in the background.
- Check the logs and confirm that the service is ready:
docker logs -f seata-server
- Confirm that the client can reach
127.0.0.1:8091before continuing.
If you later need to switch Seata Server to Nacos or another registry center, adjust the Seata Server-side registry.conf and application.yaml.
If your Seata Server uses Nacos, Seata Server 1.4.x and earlier server-side configuration is usually written in registry.conf, while Seata Server 1.5.0 and later usually uses application.yaml. For 1.4.x and earlier, for example:
registry {
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
}
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
username = ""
password = ""
}
}
registry.conf: official parameter reference and Nacos config-center example: Parameter Configuration · Nacos Configuration Center
Seata Server 1.5.0 and later usually uses application.yaml as the server-side configuration file in the Nacos scenario:
seata:
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace: ""
cluster: default
username: ""
password: ""
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace: ""
data-id: seataServer.properties
username: ""
password: ""
application.yaml: official parameter reference and Nacos registry example: Parameter Configuration · Nacos Registry Center
seatago.yml is the Seata Go client configuration file in this repository. Use it to adjust the client-side registry center, transaction group, and server address. For example:
seata:
application-id: quickstart-demo
tx-service-group: default_tx_group
data-source-proxy-mode: AT
service:
vgroup-mapping:
default_tx_group: default
grouplist:
default: 127.0.0.1:8091
registry:
type: file
client:
tm:
default-global-transaction-timeout: 60s
rm:
lock:
retry-interval: 30s
retry-times: 10
retry-policy-branch-rollback-on-conflict: true
undo:
log-serialization: json
log-table: undo_log
only-care-update-columns: true
tcc:
fence:
enable: false
References for the configuration structure and a full sample:
seatago.yml: Config struct · Full sample
Quick Integration
Install the dependency:
go get seata.apache.org/seata-go/v2@latest
Initialize the Seata client:
package main
import (
"context"
"seata.apache.org/seata-go/v2/pkg/client"
"seata.apache.org/seata-go/v2/pkg/tm"
)
func main() {
// Initialize the Seata client
client.InitPath("./conf/seatago.yml")
// Or set SEATA_GO_CONFIG_PATH=/path/to/your/seatago.yml first, then call:
// client.Init()
ctx := context.Background()
// Run business logic in a global transaction
err := tm.WithGlobalTx(ctx, &tm.GtxConfig{Name: "my-tx"}, func(ctx context.Context) error {
// Business logic
return nil
})
if err != nil {
panic(err)
}
}
Example Scenarios
AT Example
AT mode wraps business logic with tm.WithGlobalTx(...) and uses the seata-at-mysql driver to intercept database access:
import (
"context"
"database/sql"
"seata.apache.org/seata-go/v2/pkg/tm"
)
db, err := sql.Open(
"seata-at-mysql",
"root:password@tcp(127.0.0.1:3306)/seata_demo?charset=utf8mb4&parseTime=True&multiStatements=true",
)
if err != nil {
return err
}
ctx := context.Background()
err = tm.WithGlobalTx(ctx, &tm.GtxConfig{Name: "create-order"}, func(ctx context.Context) error {
_, err := db.ExecContext(ctx,
"UPDATE account SET balance = balance - ? WHERE user_id = ?",
100,
1,
)
return err
})
Before using AT mode, make sure the business database has already created the undo_log table.
Full example: AT Example.
TCC Example
TCC mode uses tcc.NewTCCServiceProxy(...) to register Try/Confirm/Cancel actions, then chains them with tm.WithGlobalTx(...):
proxy, err := tcc.NewTCCServiceProxy(&InventoryTCC{})
if err != nil {
return err
}
return tm.WithGlobalTx(ctx, &tm.GtxConfig{Name: "inventory-tcc"}, func(ctx context.Context) error {
_, err := proxy.Prepare(ctx, ReserveRequest{OrderID: 1001})
return err
})
If you need fence mode, set seata.tcc.fence.enable: true in seatago.yml and create the tcc_fence_log table.
Full example: TCC Example.
XA Example
The transaction entrypoint is the same as AT.
For MySQL XA, switch the driver to seata-xa-mysql:
db, err := sql.Open(
"seata-xa-mysql",
"root:password@tcp(127.0.0.1:3306)/seata_demo?charset=utf8mb4&parseTime=True&multiStatements=true",
)
For PostgreSQL XA, use the pgx-based driver seata-xa-postgres:
db, err := sql.Open(
"seata-xa-postgres",
"postgres://postgres:password@127.0.0.1:5432/seata_demo?sslmode=disable",
)
PostgreSQL XA relies on prepared transactions. Set
max_prepared_transactions > 0on the PostgreSQL server before using this mode.
Full example: XA Example.