GORM provides Context support, you can use it with method WithContext

Single Session Mode

Single session mode usually used when you want to perform a single operation

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

Continuous session mode

Continuous session mode usually used when you want to perform a group of operations, for example:

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

Context in Hooks/Callbacks

You could access the Context object from current Statement, for example:

  1. func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
  2. ctx := tx.Statement.Context
  3. // ...
  4. return
  5. }

Chi Middleware Example

Continuous session mode which might be helpful when handling API requests, for example, you can set up *gorm.DB with Timeout Context in middlewares, and then use the *gorm.DB when processing all requests

Following is a Chi middleware example:

  1. func SetDBMiddleware(next http.Handler) http.Handler {
  2. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  3. timeoutContext, _ := context.WithTimeout(context.Background(), time.Second)
  4. ctx := context.WithValue(r.Context(), "DB", db.WithContext(timeoutContext))
  5. next.ServeHTTP(w, r.WithContext(ctx))
  6. })
  7. }
  8. r := chi.NewRouter()
  9. r.Use(SetDBMiddleware)
  10. r.Get("/", func(w http.ResponseWriter, r *http.Request) {
  11. db, ok := ctx.Value("DB").(*gorm.DB)
  12. var users []User
  13. db.Find(&users)
  14. // lots of db operations
  15. })
  16. r.Get("/user", func(w http.ResponseWriter, r *http.Request) {
  17. db, ok := ctx.Value("DB").(*gorm.DB)
  18. var user User
  19. db.First(&user)
  20. // lots of db operations
  21. })

NOTE Set Context with WithContext is goroutine-safe, refer Session for details

Logger

Logger accepts Context too, you can use it for log tracking, refer Logger for details