我有一个大约100 req / sec的系统。有时它会在我重新启动go程序之后才会响应。我发现这是因为我打开了交易而不是在某些地方关闭它。这就是为什么所有连接都被打开的事务占用而我无法打开另一个连接之后我添加了这个代码
defer func() {
if r := recover(); r != nil {
tx.Rollback()
return
}
if err == nil {
err = tx.Commit()
} else {
tx.Rollback()
}
}()
这使我的计划工作了一个月而没有中断。但刚才它又发生了。可能是因为这个问题。有没有更好的方法来关闭交易?或者也许是一种在交易开放1分钟后关闭交易的方法?
答案 0 :(得分:0)
如果要在1分钟后回滚事务,可以使用标准的Go超时模式(如下所示)。
但是,可能有更好的方法来解决您的问题。您没有提供有关它的大量信息,但您可能正在使用带有上下文的标准HTTP请求。在这种情况下,它可能会帮助您了解a transaction started within a context is automatically rolled back when the context is cancelled。如果出现问题,确保上下文被取消的一种方法是给它deadline。
摘自Channels - Timeouts。原作者是Chris Lucas,Kwarrtz和Rodolfo Carvalho。归因详情可在contributor page上找到。该来源在CC BY-SA 3.0下获得许可,可以在Documentation archive中找到。参考主题ID:1263和示例ID:6050。
<强>超时强>
频道通常用于实现超时。
func main() {
// Create a buffered channel to prevent a goroutine leak. The buffer
// ensures that the goroutine below can eventually terminate, even if
// the timeout is met. Without the buffer, the send on the channel
// blocks forever, waiting for a read that will never happen, and the
// goroutine is leaked.
ch := make(chan struct{}, 1)
go func() {
time.Sleep(10 * time.Second)
ch <- struct{}{}
}()
select {
case <-ch:
// Work completed before timeout.
case <-time.After(1 * time.Second):
// Work was not completed after 1 second.
}
}