首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PGX在Golang进行交易

用PGX在Golang进行交易
EN

Stack Overflow用户
提问于 2021-10-01 10:59:13
回答 1查看 6.2K关注 0票数 2

我目前正在创建一个小小的Go应用程序。现在我正在处理DB部分。我使用的图书馆是这样一个:https://github.com/jackc/pgx

我遇到的问题是,每次我尝试执行数据库读取时,它都会告诉我“conn很忙”。我读过关于使用not池而不是单个连接的文章,但是它仍然不起作用。我做错了什么?

代码语言:javascript
复制
func (postgre *PostgreClient) read(query string) (pgx.Row, error) {
    client, err := postgre.client.Acquire(context.TODO())
    transaction, err := client.BeginTx(context.TODO(), pgx.TxOptions{})
    if err != nil {
        return nil, err
    }
    defer transaction.Rollback(context.TODO())

    rows := transaction.QueryRow(context.TODO(), query)
    if err != nil {
        return nil, err
    }
    err = transaction.Commit(context.TODO())
    return rows, err
}

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-01 13:04:01

在提交事务之前,必须先扫描行。

如果希望事务处理保持在函数中,则可以传递一个接口,该接口也可以在函数中进行扫描。

例如:

代码语言:javascript
复制
// implemented by *sql.Row & *sql.Rows
type Row interface {
    Scan(dst ...interface{}) error
}

// implemented by your "models"
type RowScanner interface {
    ScanRow(r Row) error
}
代码语言:javascript
复制
type User struct {
    Id    int
    Email string
}

func (u *User) ScanRow(r Row) error {
    return r.Scan(
        &u.Id,
        &u.Email,
    )
}
代码语言:javascript
复制
func (postgre *PostgreClient) read(query string, rs RowScanner) (err error) {
    conn, err := postgre.client.Acquire(context.TODO())
    if err != nil {
        return err
    }
    defer conn.Release()
    
    tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{})
    if err != nil {
        return err
    }
    defer func() {
        if err != nil {
            tx.Rollback(context.TODO())
        } else {
            tx.Commit(context.TODO())
        }
    }()

    row := tx.QueryRow(context.TODO(), query)
    if err != nil {
        return nil, err
    }
    return rs.ScanRow(row) 
}
代码语言:javascript
复制
u := new(User)
if err := pg.read("select id, email from users limit 1", u); err != nil {
    panic(err)
}

用于扫描模型列表:

代码语言:javascript
复制
type UserList []*User

func (ul *UserList) ScanRow(r Row) error {
    u := new(User)
    if err := u.ScanRow(r); err != nil {
        return err
    }

    *ul = append(*ul, u)
    return nil
}
代码语言:javascript
复制
func (postgre *PostgreClient) list(query string, rs RowScanner) (err error) {
    conn, err := postgre.client.Acquire(context.TODO())
    if err != nil {
        return err
    }
    defer conn.Release()
    
    tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{})
    if err != nil {
        return err
    }
    defer func() {
        if err != nil {
            tx.Rollback(context.TODO())
        } else {
            tx.Commit(context.TODO())
        }
    }()

    rows, err := tx.Query(context.TODO(), query)
    if err != nil {
        return err
    }
    defer rows.Close()
    
    for rows.Next() {
        if err := rs.ScanRow(rows); err != nil {
            return err
        }
    }
    return rows.Err()
}
代码语言:javascript
复制
ul := new(UserList)
if err := pg.list("select id, email from users", ul); err != nil {
    panic(err)
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69404758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档