This is an automated email from the ASF dual-hosted git repository.

flypiggy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-seata-go-samples.git


The following commit(s) were added to refs/heads/main by this push:
     new b55570b  improve: refactor and resolve the integrate test error (#87)
b55570b is described below

commit b55570b1d4c234f4a3e9b57f44269fb2e2592f73
Author: TewGuo <[email protected]>
AuthorDate: Sat Jan 31 16:59:35 2026 +0800

    improve: refactor and resolve the integrate test error (#87)
    
    Co-authored-by: guotun <[email protected]>
---
 integrate_test/at/insert_on_update/main.go  | 132 +++++++++++++---------------
 integrate_test/at/select_for_update/main.go | 129 ++++++++++++++++-----------
 2 files changed, 137 insertions(+), 124 deletions(-)

diff --git a/integrate_test/at/insert_on_update/main.go 
b/integrate_test/at/insert_on_update/main.go
index 2a326c8..8aada7b 100644
--- a/integrate_test/at/insert_on_update/main.go
+++ b/integrate_test/at/insert_on_update/main.go
@@ -21,121 +21,109 @@ import (
        "context"
        "database/sql"
        "fmt"
-       "log"
        "time"
 
-       "gorm.io/driver/mysql"
-       "gorm.io/gorm"
-       "gorm.io/gorm/clause"
        "seata.apache.org/seata-go/pkg/client"
        sql2 "seata.apache.org/seata-go/pkg/datasource/sql"
        "seata.apache.org/seata-go/pkg/tm"
 )
 
-type OrderTblModel struct {
-       Id            int64  `gorm:"column:id" json:"id"`
-       UserId        string `gorm:"column:user_id" json:"user_id"`
-       CommodityCode string `gorm:"commodity_code" json:"commodity_code"`
-       Count         int64  `gorm:"count" json:"count"`
-       Money         int64  `gorm:"money" json:"money"`
-       Descs         string `gorm:"descs" json:"descs"`
-}
+var db *sql.DB
 
 func main() {
-       initConfig()
+       client.InitPath("./conf/seatago.yml")
+       initDB()
+
+       ctx := context.Background()
 
-       // test: insert on update
-       err := tm.WithGlobalTx(context.Background(), &tm.GtxConfig{
+       // execute insert on update within global transaction
+       err := tm.WithGlobalTx(ctx, &tm.GtxConfig{
                Name:    "ATSampleLocalGlobalTx_InsertOnUpdate",
                Timeout: time.Second * 30,
        }, insertOnUpdateData)
-
        if err != nil {
-               log.Fatalf("failed to init transaction: %v", err)
-               return
+               panic(fmt.Sprintf("transaction failed: %v", err))
        }
 
-       ctx := context.Background()
-
-       // check
-       if err := checkData(ctx); err != nil {
-               fmt.Println(err)
-               panic("failed")
+       // verify data was updated correctly
+       if err := verifyData(ctx); err != nil {
+               panic(fmt.Sprintf("data verification failed: %v", err))
        }
 
-       // wait clean undo log
+       // wait for undo log cleanup
        time.Sleep(time.Second * 10)
-       if checkUndoLogData(ctx) != nil {
-               panic("failed")
+
+       // verify undo log is cleaned
+       if err := verifyUndoLogCleaned(ctx); err != nil {
+               panic(fmt.Sprintf("undo log verification failed: %v", err))
        }
-}
 
-func initConfig() {
-       client.InitPath("./conf/seatago.yml")
-       initDB()
+       fmt.Println("insert_on_update test passed")
 }
 
-var gormDB *gorm.DB
+// insertOnUpdateData tests INSERT ... ON DUPLICATE KEY UPDATE
+// The initial data has id=1, so this will trigger an UPDATE
+func insertOnUpdateData(ctx context.Context) error {
+       sql := "INSERT INTO order_tbl (id, user_id, commodity_code, count, 
money, descs) " +
+               "VALUES (?, ?, ?, ?, ?, ?) " +
+               "ON DUPLICATE KEY UPDATE count = ?, descs = ?"
 
-func initDB() {
-       sqlDB, err := sql.Open(sql2.SeataATMySQLDriver, 
"root:12345678@tcp(127.0.0.1:3306)/seata_client?multiStatements=true&interpolateParams=true")
+       result, err := db.ExecContext(ctx, sql,
+               1, "NO-100001", "C100000", 200, 10, "insert desc",
+               200, "updated by insert_on_update")
        if err != nil {
-               panic("init service error")
+               return fmt.Errorf("insert on update failed: %w", err)
        }
 
-       gormDB, err = gorm.Open(mysql.New(mysql.Config{
-               Conn: sqlDB,
-       }), &gorm.Config{})
+       rows, err := result.RowsAffected()
        if err != nil {
-               panic("open DB error")
+               return fmt.Errorf("get rows affected failed: %w", err)
        }
-}
+       fmt.Printf("insert on update affected rows: %d\n", rows)
 
-func getData() OrderTblModel {
-       return OrderTblModel{
-               Id:            1,
-               UserId:        "NO-100001",
-               CommodityCode: "C100000",
-               Count:         101,
-               Money:         10,
-               Descs:         "insert desc",
-       }
-}
-
-// insertOnUpdateData insert on update one data
-func insertOnUpdateData(ctx context.Context) error {
-       data := getData()
-
-       return 
gormDB.WithContext(ctx).Table("order_tbl").Clauses(clause.OnConflict{
-               Columns: []clause.Column{{Name: "id"}},
-               DoUpdates: clause.Assignments(map[string]interface{}{
-                       "count": data.Count,
-               }),
-       }).Create(&data).Error
+       return nil
 }
 
-func checkData(ctx context.Context) error {
-       query := getData()
+func verifyData(ctx context.Context) error {
        var count int64
-       err := 
gormDB.WithContext(ctx).Table("order_tbl").Where(query).Count(&count).Error
+       var descs string
+
+       err := db.QueryRowContext(ctx,
+               "SELECT count, descs FROM order_tbl WHERE id = ?", 
1).Scan(&count, &descs)
        if err != nil {
-               return err
+               return fmt.Errorf("query failed: %w", err)
+       }
+
+       if count != 200 {
+               return fmt.Errorf("expected count=200, got %d", count)
        }
-       fmt.Println("count:", count)
-       if count != 1 {
-               return fmt.Errorf("check data failed")
+       if descs != "updated by insert_on_update" {
+               return fmt.Errorf("expected descs='updated by 
insert_on_update', got '%s'", descs)
        }
+
+       fmt.Printf("data verified: count=%d, descs=%s\n", count, descs)
        return nil
 }
 
-func checkUndoLogData(ctx context.Context) error {
+func verifyUndoLogCleaned(ctx context.Context) error {
        var count int64
-       err := gormDB.WithContext(ctx).Table("undo_log").Count(&count).Error
+       err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM 
undo_log").Scan(&count)
        if err != nil {
-               return err
+               return fmt.Errorf("query undo_log failed: %w", err)
        }
+
        if count != 0 {
-               return fmt.Errorf("check undolog failed")
+               return fmt.Errorf("undo_log not cleaned, count=%d", count)
        }
+
+       fmt.Println("undo_log cleaned successfully")
        return nil
 }
+
+func initDB() {
+       var err error
+       db, err = sql.Open(sql2.SeataATMySQLDriver, 
"root:12345678@tcp(127.0.0.1:3306)/seata_client?multiStatements=true&interpolateParams=true")
+       if err != nil {
+               panic("init db error: " + err.Error())
+       }
+}
diff --git a/integrate_test/at/select_for_update/main.go 
b/integrate_test/at/select_for_update/main.go
index 0ef2caa..3c0b096 100644
--- a/integrate_test/at/select_for_update/main.go
+++ b/integrate_test/at/select_for_update/main.go
@@ -21,94 +21,119 @@ import (
        "context"
        "database/sql"
        "fmt"
-       "log"
        "time"
 
-       "gorm.io/driver/mysql"
-       "gorm.io/gorm"
-       "gorm.io/gorm/clause"
        "seata.apache.org/seata-go/pkg/client"
        sql2 "seata.apache.org/seata-go/pkg/datasource/sql"
        "seata.apache.org/seata-go/pkg/tm"
 )
 
-type OrderTblModel struct {
-       Id            int64  `gorm:"column:id" json:"id"`
-       UserId        string `gorm:"column:user_id" json:"user_id"`
-       CommodityCode string `gorm:"commodity_code" json:"commodity_code"`
-       Count         int64  `gorm:"count" json:"count"`
-       Money         int64  `gorm:"money" json:"money"`
-       Descs         string `gorm:"descs" json:"descs"`
-}
+var db *sql.DB
+var expectedCount int64
 
 func main() {
-       initConfig()
+       client.InitPath("./conf/seatago.yml")
+       initDB()
+
+       ctx := context.Background()
 
-       // test: select for update
-       err := tm.WithGlobalTx(context.Background(), &tm.GtxConfig{
+       // execute select for update + update within global transaction
+       err := tm.WithGlobalTx(ctx, &tm.GtxConfig{
                Name:    "ATSampleLocalGlobalTx_SelectForUpdate",
                Timeout: time.Second * 30,
-       }, selectForUpdateData)
-
+       }, selectForUpdateAndModify)
        if err != nil {
-               log.Fatalf("failed to init transaction: %v", err)
-               return
+               panic(fmt.Sprintf("transaction failed: %v", err))
        }
 
-       ctx := context.Background()
+       // verify data was updated correctly
+       if err := verifyData(ctx); err != nil {
+               panic(fmt.Sprintf("data verification failed: %v", err))
+       }
 
-       // wait clean undo log
+       // wait for undo log cleanup
        time.Sleep(time.Second * 10)
-       if checkUndoLogData(ctx) != nil {
-               panic("failed")
+
+       // verify undo log is cleaned
+       if err := verifyUndoLogCleaned(ctx); err != nil {
+               panic(fmt.Sprintf("undo log verification failed: %v", err))
        }
-}
 
-func initConfig() {
-       client.InitPath("./conf/seatago.yml")
-       initDB()
+       fmt.Println("select_for_update test passed")
 }
 
-var gormDB *gorm.DB
-
-func initDB() {
-       sqlDB, err := sql.Open(sql2.SeataATMySQLDriver, 
"root:12345678@tcp(127.0.0.1:3306)/seata_client?multiStatements=true&interpolateParams=true")
+// selectForUpdateAndModify tests SELECT ... FOR UPDATE followed by UPDATE
+// This is the typical use case: lock the row first, then modify it
+func selectForUpdateAndModify(ctx context.Context) error {
+       // step 1: select for update to lock the row
+       var id int64
+       var count int64
+       err := db.QueryRowContext(ctx,
+               "SELECT id, count FROM order_tbl WHERE id = ? FOR UPDATE", 
1).Scan(&id, &count)
+       if err != nil {
+               return fmt.Errorf("select for update failed: %w", err)
+       }
+       fmt.Printf("locked row: id=%d, count=%d\n", id, count)
+
+       // step 2: update the locked row
+       newCount := count + 50
+       expectedCount = newCount // save for verification
+       result, err := db.ExecContext(ctx,
+               "UPDATE order_tbl SET count = ?, descs = ? WHERE id = ?",
+               newCount, "updated by select_for_update", id)
        if err != nil {
-               panic("init service error")
+               return fmt.Errorf("update failed: %w", err)
        }
 
-       gormDB, err = gorm.Open(mysql.New(mysql.Config{
-               Conn: sqlDB,
-       }), &gorm.Config{})
+       rows, err := result.RowsAffected()
        if err != nil {
-               panic("open DB error")
+               return fmt.Errorf("get rows affected failed: %w", err)
        }
+       fmt.Printf("update affected rows: %d\n", rows)
+
+       return nil
 }
 
-func getData() OrderTblModel {
-       return OrderTblModel{
-               UserId:        "NO-100003",
-               CommodityCode: "C100001",
-               Count:         101,
-               Money:         11,
-               Descs:         "insert desc",
+func verifyData(ctx context.Context) error {
+       var count int64
+       var descs string
+
+       err := db.QueryRowContext(ctx,
+               "SELECT count, descs FROM order_tbl WHERE id = ?", 
1).Scan(&count, &descs)
+       if err != nil {
+               return fmt.Errorf("query failed: %w", err)
+       }
+
+       if count != expectedCount {
+               return fmt.Errorf("expected count=%d, got %d", expectedCount, 
count)
+       }
+       if descs != "updated by select_for_update" {
+               return fmt.Errorf("expected descs='updated by 
select_for_update', got '%s'", descs)
        }
-}
 
-// selectForUpdateData select for update
-func selectForUpdateData(ctx context.Context) error {
-       var data OrderTblModel
-       return 
gormDB.WithContext(ctx).Table("order_tbl").Where(&OrderTblModel{Id: 
333}).Clauses(clause.Locking{Strength: "UPDATE"}).Find(&data).Error
+       fmt.Printf("data verified: count=%d, descs=%s\n", count, descs)
+       return nil
 }
 
-func checkUndoLogData(ctx context.Context) error {
+func verifyUndoLogCleaned(ctx context.Context) error {
        var count int64
-       err := gormDB.WithContext(ctx).Table("undo_log").Count(&count).Error
+       err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM 
undo_log").Scan(&count)
        if err != nil {
-               return err
+               return fmt.Errorf("query undo_log failed: %w", err)
        }
+
        if count != 0 {
-               return fmt.Errorf("check undolog failed")
+               return fmt.Errorf("undo_log not cleaned, count=%d", count)
        }
+
+       fmt.Println("undo_log cleaned successfully")
        return nil
 }
+
+func initDB() {
+       var err error
+       db, err = sql.Open(sql2.SeataATMySQLDriver, 
"root:12345678@tcp(127.0.0.1:3306)/seata_client?multiStatements=true&interpolateParams=true")
+       if err != nil {
+               panic("init db error: " + err.Error())
+       }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to