取消正在进行的操作

您可以使用 Go context.Context 管理正在进行的操作。Context 是一个标准的 Go 数据值,它可以报告其所代表的整体操作是否已取消且不再需要。通过在应用程序的函数调用和服务中传递 context.Context,这些调用和服务可以在不再需要其处理时尽早停止工作并返回错误。有关 Context 的更多信息,请参阅 Go 并发模式:Context

例如,您可能希望

许多面向 Go 开发者的 API 包含采用 `Context` 参数的方法,让你能够更轻松地在整个应用程序中使用 `Context`。

在超时后取消数据库操作

你可以使用 `Context` 设置超时或截止时间,在此之后将取消操作。要派生具有超时或截止时间的 `Context`,请调用 `context.WithTimeout``context.WithDeadline`

以下超时示例中的代码派生了一个 `Context`,并将其传递到 `sql.DB` `QueryContext` 方法。

func QueryWithTimeout(ctx context.Context) {
    // Create a Context with a timeout.
    queryCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()

    // Pass the timeout Context with a query.
    rows, err := db.QueryContext(queryCtx, "SELECT * FROM album")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    // Handle returned rows.
}

当一个上下文派生自外部上下文时,例如本示例中 `queryCtx` 派生自 `ctx`,如果外部上下文被取消,则派生上下文也会自动被取消。例如,在 HTTP 服务器中,`http.Request.Context` 方法返回与请求关联的上下文。如果 HTTP 客户端断开连接或取消 HTTP 请求(在 HTTP/2 中可能发生),则该上下文会被取消。将 HTTP 请求的上下文传递到上面的 `QueryWithTimeout` 将导致数据库查询在以下任一情况下提前停止:HTTP 请求被取消或查询花费的时间超过五秒。

注意:始终推迟对创建具有超时或截止时间的 `Context` 时返回的 `cancel` 函数的调用。这会在包含函数退出时释放由新 `Context` 持有的资源。它还会取消 `queryCtx`,但当函数返回时,不应该再有内容使用 `queryCtx`。