首页 > 解决方案 > 使用应用程序上下文作为查询的父上下文

问题描述

我目前正在从 to 传递应用程序/主上下文,main.go以便repository.go我可以将其用作“父”上下文以与查询上下文一起使用。这是有效/惯用的用法吗?另外,我是否context.Background()应该放弃这个想法而只使用“父”上下文来代替查询上下文?

main.go

package main

import (
    "context"
    "internal/user"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    repo := user.NewRepository(ctx, db)

    // HTTP server is running.
}

内部/用户/repository.go

package user

import (
    "context"
    "database/sql"
    "time"
)

type Repository struct {
    *sql.DB
}

var appCTX context.Context

func NewRepository(ctx context.Context, db *sql.DB) Repository {
    appCTX = ctx

    return Repository{db}
}

func (r Repository) Insert(args ...interface{}) error {
    ctx, cancel := context.WithTimeout(appCTX, 5 * time.Millisecond)
    defer cancel()

    // Run query etc.
    res, err := r.ExecContext(ctx, `INSERT INTO .....`, args...)
}

标签: go

解决方案


context 的惯用用法是将其作为第一个函数参数传递,而不是存储在结构中。这是来自上下文文档:

不要将上下文存储在结构类型中;相反,将 Context 显式传递给需要它的每个函数。Context 应该是第一个参数,通常命名为 ctx

因此,即使您将主要上下文传递给您的实现,您也应该通过将上下文传递给每个操作来做到这一点。

每个独立的操作(例如 HTTP 请求)都应该创建一个新的上下文。如果您的 main 执行一个这样的独立操作,您可以像这样传递上下文。但是,如果这是一个服务器应用程序,您应该为每个请求处理程序创建一个单独的上下文。


推荐阅读