首页 > 后端开发 > Golang > 正文

Golang 如何测试数据库事务_Golang 事务回滚与提交行为验证

P粉602998670
发布: 2025-11-21 14:44:02
原创
215人浏览过
使用内存数据库或sqlmock测试Go事务。1. 用SQLite测试回滚:插入数据后调用Rollback,验证数据未保存;2. 测试Commit后数据持久化;3. 模拟错误触发Rollback,确保无脏数据;4. 用sqlmock模拟事务流程,验证执行顺序。

golang 如何测试数据库事务_golang 事务回滚与提交行为验证

在 Go 语言中测试数据库事务的关键在于验证事务的提交与回滚行为是否符合预期。我们通常使用 sql.Tx 来管理事务,并借助测试工具模拟真实场景,确保数据一致性。下面介绍如何有效测试事务中的回滚和提交逻辑。

使用内存数据库进行事务测试

推荐使用支持事务的内存数据库(如 SQLite)来加速测试并避免依赖外部环境。

注意:MySQL 和 PostgreSQL 的驱动也可以配合 Docker 容器使用,但 SQLite 更轻量,适合单元测试。

示例代码:

package main

import (
    "database/sql"
    "log"
    "testing"

    _ "github.com/mattn/go-sqlite3"
)

func setupTestDB() *sql.DB {
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        log.Fatal(err)
    }

    _, err = db.Exec(`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)`)
    if err != nil {
        log.Fatal(err)
    }

    return db
}

func insertUser(tx *sql.Tx, name string) error {
    _, err := tx.Exec("INSERT INTO users (name) VALUES (?)", name)
    return err
}
登录后复制

编写测试函数验证回滚:

立即学习go语言免费学习笔记(深入)”;

func TestTransaction_Rollback(t *testing.T) {
    db := setupTestDB()
    defer db.Close()

    tx, _ := db.Begin()

    err := insertUser(tx, "Alice")
    if err != nil {
        t.Fatal(err)
    }

    // 不调用 Commit,直接 Rollback
    tx.Rollback()

    var count int
    err = db.QueryRow("SELECT COUNT(*) FROM users WHERE name = ?", "Alice").Scan(&count)
    if err != nil {
        t.Fatal(err)
    }

    if count != 0 {
        t.Errorf("expected no user after rollback, but got %d", count)
    }
}
登录后复制

验证事务提交是否生效

测试提交后数据应持久化到数据库。

func TestTransaction_Commit(t *testing.T) {
    db := setupTestDB()
    defer db.Close()

    tx, _ := db.Begin()

    err := insertUser(tx, "Bob")
    if err != nil {
        t.Fatal(err)
    }

    err = tx.Commit()
    if err != nil {
        t.Fatal(err)
    }

    var count int
    err = db.QueryRow("SELECT COUNT(*) FROM users WHERE name = ?", "Bob").Scan(&count)
    if err != nil {
        t.Fatal(err)
    }

    if count != 1 {
        t.Errorf("expected 1 user after commit, but got %d", count)
    }
}
登录后复制

模拟错误触发自动回滚

实际业务中常因操作失败需回滚事务。可在插入非法数据时测试自动回滚行为。

例如:插入违反约束的数据(如空名称),然后回滚。

落笔AI
落笔AI

AI写作,AI写网文、AI写长篇小说、短篇小说

落笔AI 41
查看详情 落笔AI
func TestTransaction_ErrorHandling(t *testing.T) {
    db := setupTestDB()
    defer db.Close()

    tx, _ := db.Begin()

    err := insertUser(tx, "")
    if err != nil {
        tx.Rollback() // 显式回滚
    } else {
        tx.Commit()
    }

    var count int
    err = db.QueryRow("SELECT COUNT(*) FROM users WHERE name = ''").Scan(&count)
    if err != nil {
        t.Fatal(err)
    }

    if count != 0 {
        t.Errorf("expected no empty-name user after rollback, but got %d", count)
    }
}
登录后复制

这种写法能确保即使插入失败,也不会留下脏数据。

使用 sqlmock 模拟事务流程(高级测试)

对于不希望真正连接数据库的场景,可用 sqlmock 库模拟事务行为。

安装:

go get github.com/DATA-DOG/go-sqlmock
登录后复制

示例测试:

import (
    "testing"
    "github.com/DATA-DOG/go-sqlmock"
)

func TestWithSqlMock(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("failed to open sqlmock: %v", err)
    }
    defer db.Close()

    mock.ExpectBegin()
    mock.ExpectExec("INSERT INTO users").WillReturnResult(sqlmock.NewResult(1, 1))
    mock.ExpectRollback() // 假设我们回滚

    tx, _ := db.Begin()
    tx.Exec("INSERT INTO users (name) VALUES (?)", "Charlie")
    tx.Rollback()

    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("unfulfilled expectations: %s", err)
    }
}
登录后复制

这种方式适合集成测试或服务层逻辑验证,无需真实数据库。

基本上就这些。通过内存数据库或 mock 工具,可以完整覆盖事务的提交、回滚和异常处理路径,保证业务逻辑正确性。

以上就是Golang 如何测试数据库事务_Golang 事务回滚与提交行为验证的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号