【问题标题】:How to set timeout for long running queries in gorm如何在gorm中为长时间运行的查询设置超时
【发布时间】:2020-11-20 12:30:31
【问题描述】:

有没有办法在运行长查询时将 gorm 设置为在可配置的时间段后超时?我正在使用 mssql。我浏览了文档,还没有找到方法。

【问题讨论】:

  • 您可以尝试传入一个超时设置为db.WithContext() 的上下文,并将其与您的查询链接起来。
  • 这个问题是我已经对我的查询进行了线程化,并且将一个接一个地运行一个查询。我不希望链接与数据库的上下文,只需要一个单独的查询。

标签: sql-server go go-gorm


【解决方案1】:

gorm 目前似乎没有实现任何接受context.Context 作为参数的查询,例如QueryRowContext 正在做。
您可以创建一种解决方法并使用 Context 使您的查询“过期”。

type QueryResponse struct {
    MyResult *MyResult
    Error    error
}

func queryHelper(ctx context.Context) <- chan *QueryResponse {
    chResult := make(chan *QueryResponse, 1)
    go func() {
        //your query here
        //...
        //blah blah check stuff do whatever you want
        //err is an error that comes from the query code
        if err != nil {
            chResult <- &QueryResponse{nil, err}
            return
        }
        chResult <- &QueryResponse{queryResponse, nil}
    } ()
    return chResult
}

func MyQueryFunction(ctx context.Context) (*MyResult, error) {
    select {
    case <-ctx.Done():
        return nil, fmt.Errorf("context timeout, query out of time")

    case res := <-queryHelper(ctx):
        return res.MyResult, res.Error
    }
}

然后在你的上层函数中,你可以创建一个上下文并将它传递给MyQueryFunction。如果查询超过您设置的时间,则会引发错误,您应该(必须)检查它。

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
res, err := MyQueryFunction(ctx)
if err != nil {
    fmt.Printf("err %v", err)
} else {
    fmt.Printf("res %v", res)
}

当然,这是一个例子,没有考虑很多用例,必须优先考虑框架内的正确实现。

【讨论】:

  • 也许有更好的方法,我们仍然可以使用 QueryContext() 但从 gorm 中提取 sql 查询字符串并将其放在查询上下文中。有没有一种方法可以使用 gorm 语法创建查询,而不是使用 find 或 scan 来执行它,而只需提取查询的字符串化版本并将其放入 QueryContext() 中?
【解决方案2】:

这段代码似乎对我有用,而且非常干净。我猜只是使用交易。

    //Gorm query below
query = query.Where(whereClause)
//Set up Timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var x sql.TxOptions
db := query.BeginTx(ctx, &x)
defer db.Commit()
// Execute the query
if err := db.Find(*results).Error; err != nil {
    return err
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-28
    • 2020-01-28
    • 2011-06-04
    • 2014-08-06
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2017-07-01
    相关资源
    最近更新 更多