使用Go语言例程时,我为每个例程设置了最长30秒的截止时间,代码如下:
func processLibs(ctx context.Context, libs []Library) {
for _, lib := range libs {
go processLib(ctx, lib)
}
}
func processLib(ctx context.Context, lib Library) {
cancelContext, cancel := context.WithTimeout(ctx, time.Second * 30)
defer cancel()
if err := persistLib(cancelContext, lib); err != nil {
log.Error("error persisting library", log.Err(err))
}
}
其中persistLib对数据库执行7次查询(最大连接数和最大空闲连接数等于5),并对另一个服务器执行一次请求(传出请求的时间是可以的)。我知道一个事实,即库的长度小于或等于100。
我遇到的问题是,有时候,我有一批错误(大约20%的go例程)说上下文过期了,但我觉得很奇怪,一个go例程只需要30秒(测量一下,应该没问题)。
我试着将go例程的数量减少到70或50个,但问题仍然存在。我也试着检查性能的改进,但有些go例程在第一次查询的中间发送了一个截止日期错误,有些是在go例程执行的最后,这取决于情况。
我的数据库是一个MySQL 8.0和我使用的GO 1.19.
1条答案
按热度按时间1zmg4dgp1#
真实的的问题是,您希望在这里超时哪个事务?或者换句话说,您希望在30秒内完成哪个事务?查看代码,您只需要将 persistLib 调用为
这样,您将在每个持久化操作上等待30秒。当前您的代码正在所有持久化操作上等待 ctx 中设置的任何秒数。