0

我有一个大约 100 req/sec 的系统。有时它直到我重新启动我的 go 程序才会响应。我发现这是因为我打开了事务并且在某些地方没有关闭它。这就是为什么所有连接都被打开的事务占用而我无法打开另一个连接之后我添加了这段代码

defer func() {
if r := recover(); r != nil {
    tx.Rollback()
    return
}

if err == nil {
    err = tx.Commit()
} else {
    tx.Rollback()
}
}()

这使我的程序可以不间断地运行一个月。可就在刚才,又发生了。大概是因为这个问题。有没有更好的方法来关闭交易?或者,如果交易打开 1 分钟,它可能是一种关闭交易的方法?

4

1 回答 1

2

如果您想在 1 分钟后回滚事务,可以使用标准的 Go 超时模式(如下)。

但是,可能有更好的方法来处理您的问题。您没有提供很多有关它的信息,但您可能正在使用带有上下文的标准 HTTP 请求。在这种情况下,它可以帮助您知道在上下文中启动的事务在上下文被取消时会自动回滚。确保在出现问题时取消上下文的一种方法是给它一个截止日期


摘自Channels - Timeouts。最初的作者是Chris LucasKwarrtzRodolfo Carvalho。可以在贡献者页面上找到归属详细信息。源代码在CC BY-SA 3.0下获得许可,可以在文档存档中找到。参考主题 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.
    }
}
于 2017-03-19T17:25:58.533 回答