如何在 gorm 中为长 运行 查询设置超时
How to set timeout for long running queries in gorm
有什么方法可以让 gorm 在 运行 长查询时在一段可配置的时间后超时?我正在使用 mssql。我已经查看了文档,但还没有找到方法。
gorm 目前似乎没有实现任何接受参数 a context.Context
的查询,例如QueryRowContext
正在做。
您可以创建一个解决方法并使用上下文使您的查询“过期”。
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)
}
当然,这是一个例子,没有考虑很多用例,必须优先考虑框架内的适当实现。
这段代码似乎对我有用,而且非常干净。我猜只是使用事务。
//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
}
有什么方法可以让 gorm 在 运行 长查询时在一段可配置的时间后超时?我正在使用 mssql。我已经查看了文档,但还没有找到方法。
gorm 目前似乎没有实现任何接受参数 a context.Context
的查询,例如QueryRowContext
正在做。
您可以创建一个解决方法并使用上下文使您的查询“过期”。
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)
}
当然,这是一个例子,没有考虑很多用例,必须优先考虑框架内的适当实现。
这段代码似乎对我有用,而且非常干净。我猜只是使用事务。
//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
}