コンテキスト

WithContextメソッドによって有効化されるGORMのコンテキストサポートは、Goアプリケーションにおけるデータベース操作の柔軟性と制御を強化する強力な機能です。さまざまな操作モード、タイムアウト設定、さらにはフック/コールバックやミドルウェアへの統合など、コンテキスト管理を可能にします。これらのさまざまな側面について詳しく見ていきましょう。

シングルセッションモード

シングルセッションモードは、個々の操作を実行するのに適しています。特定の操作がコンテキストのスコープ内で実行されることを保証し、より良い制御と監視を可能にします。

db.WithContext(ctx).Find(&users)

連続セッションモード

連続セッションモードは、一連の関連操作を実行するのに最適です。これらの操作全体でコンテキストを維持するため、トランザクションなどのシナリオで特に役立ちます。

tx := db.WithContext(ctx)
tx.First(&user, 1)
tx.Model(&user).Update("role", "admin")

コンテキストタイムアウト

db.WithContextに渡されるコンテキストにタイムアウトを設定することで、長時間実行されるクエリの期間を制御できます。これは、パフォーマンスを維持し、データベースインタラクションにおけるリソースのロックアップを回避するために重要です。

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

db.WithContext(ctx).Find(&users)

フック/コールバックにおけるコンテキスト

コンテキストは、GORMのフック/コールバック内でもアクセスできます。これにより、これらのライフサイクルイベント中にコンテキスト情報を使用できます。

func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
ctx := tx.Statement.Context
// ... use context
return
}

Chiミドルウェアとの統合

GORMのコンテキストサポートは、ChiルーターなどのWebサーバーミドルウェアにも拡張されます。これにより、Webリクエストのスコープ内で、すべてのデータベース操作に対してタイムアウトを設定したコンテキストを設定できます。

func SetDBMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
timeoutContext, _ := context.WithTimeout(context.Background(), time.Second)
ctx := context.WithValue(r.Context(), "DB", db.WithContext(timeoutContext))
next.ServeHTTP(w, r.WithContext(ctx))
})
}

// Router setup
r := chi.NewRouter()
r.Use(SetDBMiddleware)

// Route handlers
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
db, ok := r.Context().Value("DB").(*gorm.DB)
// ... db operations
})

r.Get("/user", func(w http.ResponseWriter, r *http.Request) {
db, ok := r.Context().Value("DB").(*gorm.DB)
// ... db operations
})

WithContextを使用してContextを設定することは、ゴルーチンセーフです。これにより、複数のゴルーチンにわたってデータベース操作が安全に管理されます。詳細については、GORMのセッションドキュメントを参照してください。

ロガーの統合

GORMのロガーはContextも受け入れます。これは、ログの追跡や既存のロギングインフラストラクチャとの統合に使用できます。

詳細については、ロガードキュメントを参照してください。

プラチナスポンサー

ゴールドスポンサー

プラチナスポンサー

ゴールドスポンサー