取消進行中的操作

您可以使用 Go context.Context 來管理進行中的作業。Context 是標準的 Go 資料值,可以報告它所代表的整體作業是否已取消且不再需要。透過在應用程式中跨函式呼叫和服務傳遞 context.Context,這些作業可以在不再需要其處理程序時提早停止工作並傳回錯誤。如需進一步瞭解 Context,請參閱 Go 並行模式:Context

例如,您可能想要

許多針對 Go 開發人員的 API 都包含採用 Context 參數的方法,讓您更容易在整個應用程式中使用 Context

在逾時後取消資料庫作業

您可以使用 Context 設定作業將在之後取消的逾時或截止時間。若要衍生具有逾時或截止時間的 Context,請呼叫 context.WithTimeoutcontext.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.
}

當一個 context 衍生自外部 context(如本範例中 queryCtx 衍生自 ctx),如果外部 context 已取消,則衍生的 context 也會自動取消。例如,在 HTTP 伺服器中,http.Request.Context 方法會傳回與要求相關聯的 context。如果 HTTP 客戶端中斷連線或取消 HTTP 要求(在 HTTP/2 中有可能),則該 context 會取消。將 HTTP 要求的 context 傳遞至上述的 QueryWithTimeout 會導致資料庫查詢在以下任一情況下提早停止:整體 HTTP 要求已取消,或查詢花費超過五秒鐘。

注意:請務必延遲呼叫在建立具有逾時或截止時間的新 Context 時傳回的 cancel 函式。這會在包含函式結束時釋放由新 Context 持有的資源。它也會取消 queryCtx,但當函式傳回時,不應該再有其他項目使用 queryCtx