为了账号安全,请及时绑定邮箱和手机立即绑定

与PGX在高浪的交易

与PGX在高浪的交易

Go
白衣染霜花 2022-10-04 17:13:14
我目前正在创建一个小的Go应用程序。现在我正在研究DB部分。我使用的库是这样的:https://github.com/jackc/pgx我遇到的问题是,每次我尝试执行数据库读取时,它都告诉我我的“conn很忙”。我读到了有关使用pgxpool而不是单个连接的信息,但它仍然不起作用。我做错了什么?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}提前致谢。
查看完整描述

1 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

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


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


例如:


// implemented by *sql.Row & *sql.Rows

type Row interface {

    Scan(dst ...interface{}) error

}


// implemented by your "models"

type RowScanner interface {

    ScanRow(r Row) error

}

type User struct {

    Id    int

    Email string

}


func (u *User) ScanRow(r Row) error {

    return r.Scan(

        &u.Id,

        &u.Email,

    )

}

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) 

}

u := new(User)

if err := pg.read("select id, email from users limit 1", u); err != nil {

    panic(err)

}

要扫描模型列表:


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

}

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()

}

ul := new(UserList)

if err := pg.list("select id, email from users", ul); err != nil {

    panic(err)

}


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 65 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信