取消進行中的操作
您可以使用 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.
}
當一個 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
。