From 044c754ea53f5b81f451451df53aea366f6f700a Mon Sep 17 00:00:00 2001
From: KN4CK3R <admin@oldschoolhack.me>
Date: Sat, 19 Nov 2022 09:12:33 +0100
Subject: [PATCH] Add `context.Context` to more methods (#21546)

This PR adds a context parameter to a bunch of methods. Some helper
`xxxCtx()` methods got replaced with the normal name now.

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
---
 cmd/admin.go                                  |   2 +-
 models/activities/action.go                   |  18 +-
 models/activities/action_test.go              |  10 +-
 models/activities/notification.go             |  96 +++---
 models/activities/notification_test.go        |   8 +-
 models/db/consistency.go                      |  15 +-
 models/db/engine_test.go                      |   4 +-
 models/db/sequence.go                         |   5 +-
 models/fixture_generation.go                  |   2 +-
 models/git/protected_tag.go                   |  17 +-
 models/git/protected_tag_test.go              |  19 +-
 models/issues/assignees.go                    |   9 +-
 models/issues/assignees_test.go               |  10 +-
 models/issues/comment.go                      |  63 ++--
 models/issues/comment_list.go                 |  30 +-
 models/issues/issue.go                        | 120 +++----
 models/issues/issue_list.go                   |  38 +--
 models/issues/issue_list_test.go              |   3 +-
 models/issues/issue_project.go                |  12 +-
 models/issues/issue_test.go                   |   4 +-
 models/issues/issue_xref.go                   |   2 +-
 models/issues/label.go                        |  44 +--
 models/issues/label_test.go                   |   4 +-
 models/issues/pull.go                         |  66 ++--
 models/issues/pull_list.go                    |   2 +-
 models/issues/pull_test.go                    |  30 +-
 models/issues/review.go                       |  20 +-
 models/issues/review_test.go                  |   2 +-
 models/org_team_test.go                       |   2 +-
 models/perm/access/access_test.go             |  14 +-
 models/perm/access/repo_permission.go         |  12 +-
 models/repo/attachment.go                     |  12 +-
 models/repo/pushmirror.go                     |   4 +-
 models/repo/release.go                        |  16 +-
 models/repo/repo.go                           |  24 +-
 models/repo/repo_list.go                      |  11 +-
 models/repo/repo_list_test.go                 |  18 +-
 models/repo/user_repo.go                      |  10 +-
 models/user/user.go                           |  12 +-
 models/user/user_test.go                      |   8 +-
 modules/convert/issue.go                      |  29 +-
 modules/convert/issue_comment.go              |  27 +-
 modules/convert/pull.go                       |   6 +-
 modules/convert/pull_test.go                  |   9 +-
 modules/doctor/dbconsistency.go               |  22 +-
 modules/indexer/issues/indexer.go             |  18 +-
 modules/notification/action/action.go         | 117 +++----
 modules/notification/action/action_test.go    |   3 +-
 modules/notification/base/notifier.go         |  90 ++---
 modules/notification/base/null.go             |  92 ++---
 modules/notification/indexer/indexer.go       |  44 +--
 modules/notification/mail/mail.go             |  91 ++---
 modules/notification/mirror/mirror.go         |  14 +-
 modules/notification/notification.go          | 180 +++++-----
 modules/notification/ui/ui.go                 |  47 +--
 modules/notification/webhook/webhook.go       | 321 +++++++-----------
 modules/repository/repo.go                    |   2 +-
 routers/api/packages/conan/conan.go           |   2 +-
 routers/api/v1/misc/nodeinfo.go               |   2 +-
 routers/api/v1/notify/repo.go                 |   8 +-
 routers/api/v1/notify/threads.go              |   8 +-
 routers/api/v1/notify/user.go                 |   8 +-
 routers/api/v1/org/team.go                    |   8 +-
 routers/api/v1/repo/branch.go                 |  12 +-
 routers/api/v1/repo/fork.go                   |   2 +-
 routers/api/v1/repo/issue.go                  |  28 +-
 routers/api/v1/repo/issue_comment.go          |  24 +-
 routers/api/v1/repo/issue_reaction.go         |   4 +-
 routers/api/v1/repo/issue_tracked_time.go     |  10 +-
 routers/api/v1/repo/migrate.go                |   2 +-
 routers/api/v1/repo/pull.go                   |  52 +--
 routers/api/v1/repo/pull_review.go            |   4 +-
 routers/api/v1/repo/release.go                |   8 +-
 routers/api/v1/repo/release_attachment.go     |   2 +-
 routers/api/v1/repo/release_tags.go           |   2 +-
 routers/api/v1/repo/repo.go                   |   4 +-
 routers/api/v1/repo/wiki.go                   |   6 +-
 routers/api/v1/user/repo.go                   |   6 +-
 routers/api/v1/user/star.go                   |  11 +-
 routers/api/v1/user/watch.go                  |  11 +-
 routers/private/hook_post_receive.go          |   2 +-
 routers/private/hook_pre_receive.go           |   4 +-
 routers/web/explore/repo.go                   |   2 +-
 routers/web/home.go                           |   2 +-
 routers/web/org/home.go                       |   2 +-
 routers/web/repo/branch.go                    |   8 +-
 routers/web/repo/compare.go                   |   4 +-
 routers/web/repo/issue.go                     |  60 ++--
 routers/web/repo/issue_label.go               |   2 +-
 routers/web/repo/projects.go                  |   4 +-
 routers/web/repo/pull.go                      |  30 +-
 routers/web/repo/pull_review.go               |   4 +-
 routers/web/repo/release.go                   |   8 +-
 routers/web/repo/repo.go                      |   2 +-
 routers/web/repo/tag.go                       |   4 +-
 routers/web/repo/wiki.go                      |   6 +-
 routers/web/user/home.go                      |   6 +-
 routers/web/user/notification.go              | 220 ++++++------
 routers/web/user/profile.go                   |   6 +-
 services/agit/agit.go                         |  10 +-
 services/asymkey/sign.go                      |   2 +-
 services/automerge/automerge.go               |   8 +-
 services/comments/comments.go                 |  34 +-
 services/issue/assignee.go                    |  10 +-
 services/issue/content.go                     |   3 +-
 services/issue/issue.go                       |  18 +-
 services/issue/label.go                       |  10 +-
 services/issue/milestone.go                   |   2 +-
 services/issue/status.go                      |   2 +-
 services/lfs/locks.go                         |   8 +-
 services/mailer/mail.go                       |   9 +-
 services/mailer/mail_issue.go                 |  20 +-
 services/mailer/mail_release.go               |   2 +-
 services/mailer/mail_repo.go                  |   6 +-
 services/migrations/gitea_uploader_test.go    |  12 +-
 services/mirror/mirror_pull.go                |   8 +-
 services/packages/packages.go                 |   6 +-
 services/pull/check.go                        |  14 +-
 services/pull/commit_status.go                |   4 +-
 services/pull/edits.go                        |   2 +-
 services/pull/merge.go                        |  36 +-
 services/pull/patch.go                        |   2 +-
 services/pull/pull.go                         |  48 +--
 services/pull/pull_test.go                    |  13 +-
 services/pull/review.go                       |  18 +-
 services/pull/temp_repo.go                    |   4 +-
 services/pull/update.go                       |   8 +-
 services/release/release.go                   |  42 +--
 services/release/release_test.go              |  12 +-
 services/repository/adopt.go                  |   2 +-
 services/repository/branch.go                 |   5 +-
 services/repository/fork.go                   |   2 +-
 services/repository/push.go                   |  14 +-
 services/repository/repository.go             |   4 +-
 services/repository/template.go               |   2 +-
 services/repository/transfer.go               |   6 +-
 services/task/migrate.go                      |   2 +-
 services/user/user.go                         |   2 +-
 services/webhook/webhook.go                   |   2 +-
 .../user/notification/notification_div.tmpl   |   5 +-
 tests/integration/api_comment_test.go         |   5 +-
 tests/integration/api_issue_reaction_test.go  |   2 +-
 tests/integration/api_notification_test.go    |   5 +-
 tests/integration/api_pull_commits_test.go    |   9 +-
 tests/integration/api_pull_test.go            |   5 +-
 tests/integration/eventsource_test.go         |   3 +-
 tests/integration/pull_update_test.go         |   8 +-
 tests/integration/repo_tag_test.go            |   9 +-
 148 files changed, 1411 insertions(+), 1564 deletions(-)

diff --git a/cmd/admin.go b/cmd/admin.go
index d33d17a53..80b5d4853 100644
--- a/cmd/admin.go
+++ b/cmd/admin.go
@@ -727,7 +727,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
 
 	log.Trace("Synchronizing repository releases (this may take a while)")
 	for page := 1; ; page++ {
-		repos, count, err := repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+		repos, count, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
 			ListOptions: db.ListOptions{
 				PageSize: repo_model.RepositoryListDefaultPageSize,
 				Page:     page,
diff --git a/models/activities/action.go b/models/activities/action.go
index 5c3419c5e..bbb607326 100644
--- a/models/activities/action.go
+++ b/models/activities/action.go
@@ -461,7 +461,8 @@ func DeleteOldActions(olderThan time.Duration) (err error) {
 	return err
 }
 
-func notifyWatchers(ctx context.Context, actions ...*Action) error {
+// NotifyWatchers creates batch of actions for every watcher.
+func NotifyWatchers(ctx context.Context, actions ...*Action) error {
 	var watchers []*repo_model.Watch
 	var repo *repo_model.Repository
 	var err error
@@ -565,11 +566,6 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
 	return nil
 }
 
-// NotifyWatchers creates batch of actions for every watcher.
-func NotifyWatchers(actions ...*Action) error {
-	return notifyWatchers(db.DefaultContext, actions...)
-}
-
 // NotifyWatchersActions creates batch of actions for every watcher.
 func NotifyWatchersActions(acts []*Action) error {
 	ctx, committer, err := db.TxContext(db.DefaultContext)
@@ -578,7 +574,7 @@ func NotifyWatchersActions(acts []*Action) error {
 	}
 	defer committer.Close()
 	for _, act := range acts {
-		if err := notifyWatchers(ctx, act); err != nil {
+		if err := NotifyWatchers(ctx, act); err != nil {
 			return err
 		}
 	}
@@ -603,17 +599,17 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error {
 }
 
 // CountActionCreatedUnixString count actions where created_unix is an empty string
-func CountActionCreatedUnixString() (int64, error) {
+func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
 	if setting.Database.UseSQLite3 {
-		return db.GetEngine(db.DefaultContext).Where(`created_unix = ""`).Count(new(Action))
+		return db.GetEngine(ctx).Where(`created_unix = ""`).Count(new(Action))
 	}
 	return 0, nil
 }
 
 // FixActionCreatedUnixString set created_unix to zero if it is an empty string
-func FixActionCreatedUnixString() (int64, error) {
+func FixActionCreatedUnixString(ctx context.Context) (int64, error) {
 	if setting.Database.UseSQLite3 {
-		res, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
+		res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
 		if err != nil {
 			return 0, err
 		}
diff --git a/models/activities/action_test.go b/models/activities/action_test.go
index ac2a3043a..b79eb0d08 100644
--- a/models/activities/action_test.go
+++ b/models/activities/action_test.go
@@ -188,7 +188,7 @@ func TestNotifyWatchers(t *testing.T) {
 		RepoID:    1,
 		OpType:    activities_model.ActionStarRepo,
 	}
-	assert.NoError(t, activities_model.NotifyWatchers(action))
+	assert.NoError(t, activities_model.NotifyWatchers(db.DefaultContext, action))
 
 	// One watchers are inactive, thus action is only created for user 8, 1, 4, 11
 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
@@ -256,17 +256,17 @@ func TestConsistencyUpdateAction(t *testing.T) {
 	//
 	// Get rid of incorrectly set created_unix
 	//
-	count, err := activities_model.CountActionCreatedUnixString()
+	count, err := activities_model.CountActionCreatedUnixString(db.DefaultContext)
 	assert.NoError(t, err)
 	assert.EqualValues(t, 1, count)
-	count, err = activities_model.FixActionCreatedUnixString()
+	count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
 	assert.NoError(t, err)
 	assert.EqualValues(t, 1, count)
 
-	count, err = activities_model.CountActionCreatedUnixString()
+	count, err = activities_model.CountActionCreatedUnixString(db.DefaultContext)
 	assert.NoError(t, err)
 	assert.EqualValues(t, 0, count)
-	count, err = activities_model.FixActionCreatedUnixString()
+	count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
 	assert.NoError(t, err)
 	assert.EqualValues(t, 0, count)
 
diff --git a/models/activities/notification.go b/models/activities/notification.go
index 28adc8cc4..10b3a7671 100644
--- a/models/activities/notification.go
+++ b/models/activities/notification.go
@@ -136,49 +136,41 @@ func GetNotifications(ctx context.Context, options *FindNotificationOptions) (nl
 }
 
 // CountNotifications count all notifications that fit to the given options and ignore pagination.
-func CountNotifications(opts *FindNotificationOptions) (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(opts.ToCond()).Count(&Notification{})
+func CountNotifications(ctx context.Context, opts *FindNotificationOptions) (int64, error) {
+	return db.GetEngine(ctx).Where(opts.ToCond()).Count(&Notification{})
 }
 
 // CreateRepoTransferNotification creates  notification for the user a repository was transferred to
-func CreateRepoTransferNotification(doer, newOwner *user_model.User, repo *repo_model.Repository) error {
-	ctx, committer, err := db.TxContext(db.DefaultContext)
-	if err != nil {
-		return err
-	}
-	defer committer.Close()
+func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error {
+	return db.AutoTx(ctx, func(ctx context.Context) error {
+		var notify []*Notification
 
-	var notify []*Notification
-
-	if newOwner.IsOrganization() {
-		users, err := organization.GetUsersWhoCanCreateOrgRepo(ctx, newOwner.ID)
-		if err != nil || len(users) == 0 {
-			return err
-		}
-		for i := range users {
-			notify = append(notify, &Notification{
-				UserID:    users[i].ID,
+		if newOwner.IsOrganization() {
+			users, err := organization.GetUsersWhoCanCreateOrgRepo(ctx, newOwner.ID)
+			if err != nil || len(users) == 0 {
+				return err
+			}
+			for i := range users {
+				notify = append(notify, &Notification{
+					UserID:    users[i].ID,
+					RepoID:    repo.ID,
+					Status:    NotificationStatusUnread,
+					UpdatedBy: doer.ID,
+					Source:    NotificationSourceRepository,
+				})
+			}
+		} else {
+			notify = []*Notification{{
+				UserID:    newOwner.ID,
 				RepoID:    repo.ID,
 				Status:    NotificationStatusUnread,
 				UpdatedBy: doer.ID,
 				Source:    NotificationSourceRepository,
-			})
+			}}
 		}
-	} else {
-		notify = []*Notification{{
-			UserID:    newOwner.ID,
-			RepoID:    repo.ID,
-			Status:    NotificationStatusUnread,
-			UpdatedBy: doer.ID,
-			Source:    NotificationSourceRepository,
-		}}
-	}
 
-	if err := db.Insert(ctx, notify); err != nil {
-		return err
-	}
-
-	return committer.Commit()
+		return db.Insert(ctx, notify)
+	})
 }
 
 // CreateOrUpdateIssueNotifications creates an issue notification
@@ -379,11 +371,7 @@ func CountUnread(ctx context.Context, userID int64) int64 {
 }
 
 // LoadAttributes load Repo Issue User and Comment if not loaded
-func (n *Notification) LoadAttributes() (err error) {
-	return n.loadAttributes(db.DefaultContext)
-}
-
-func (n *Notification) loadAttributes(ctx context.Context) (err error) {
+func (n *Notification) LoadAttributes(ctx context.Context) (err error) {
 	if err = n.loadRepo(ctx); err != nil {
 		return
 	}
@@ -481,10 +469,10 @@ func (n *Notification) APIURL() string {
 type NotificationList []*Notification
 
 // LoadAttributes load Repo Issue User and Comment if not loaded
-func (nl NotificationList) LoadAttributes() error {
+func (nl NotificationList) LoadAttributes(ctx context.Context) error {
 	var err error
 	for i := 0; i < len(nl); i++ {
-		err = nl[i].LoadAttributes()
+		err = nl[i].LoadAttributes(ctx)
 		if err != nil && !issues_model.IsErrCommentNotExist(err) {
 			return err
 		}
@@ -504,7 +492,7 @@ func (nl NotificationList) getPendingRepoIDs() []int64 {
 }
 
 // LoadRepos loads repositories from database
-func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error) {
+func (nl NotificationList) LoadRepos(ctx context.Context) (repo_model.RepositoryList, []int, error) {
 	if len(nl) == 0 {
 		return repo_model.RepositoryList{}, []int{}, nil
 	}
@@ -517,7 +505,7 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
 		if left < limit {
 			limit = left
 		}
-		rows, err := db.GetEngine(db.DefaultContext).
+		rows, err := db.GetEngine(ctx).
 			In("id", repoIDs[:limit]).
 			Rows(new(repo_model.Repository))
 		if err != nil {
@@ -578,7 +566,7 @@ func (nl NotificationList) getPendingIssueIDs() []int64 {
 }
 
 // LoadIssues loads issues from database
-func (nl NotificationList) LoadIssues() ([]int, error) {
+func (nl NotificationList) LoadIssues(ctx context.Context) ([]int, error) {
 	if len(nl) == 0 {
 		return []int{}, nil
 	}
@@ -591,7 +579,7 @@ func (nl NotificationList) LoadIssues() ([]int, error) {
 		if left < limit {
 			limit = left
 		}
-		rows, err := db.GetEngine(db.DefaultContext).
+		rows, err := db.GetEngine(ctx).
 			In("id", issueIDs[:limit]).
 			Rows(new(issues_model.Issue))
 		if err != nil {
@@ -662,7 +650,7 @@ func (nl NotificationList) getPendingCommentIDs() []int64 {
 }
 
 // LoadComments loads comments from database
-func (nl NotificationList) LoadComments() ([]int, error) {
+func (nl NotificationList) LoadComments(ctx context.Context) ([]int, error) {
 	if len(nl) == 0 {
 		return []int{}, nil
 	}
@@ -675,7 +663,7 @@ func (nl NotificationList) LoadComments() ([]int, error) {
 		if left < limit {
 			limit = left
 		}
-		rows, err := db.GetEngine(db.DefaultContext).
+		rows, err := db.GetEngine(ctx).
 			In("id", commentIDs[:limit]).
 			Rows(new(issues_model.Comment))
 		if err != nil {
@@ -775,8 +763,8 @@ func SetRepoReadBy(ctx context.Context, userID, repoID int64) error {
 }
 
 // SetNotificationStatus change the notification status
-func SetNotificationStatus(notificationID int64, user *user_model.User, status NotificationStatus) (*Notification, error) {
-	notification, err := getNotificationByID(db.DefaultContext, notificationID)
+func SetNotificationStatus(ctx context.Context, notificationID int64, user *user_model.User, status NotificationStatus) (*Notification, error) {
+	notification, err := GetNotificationByID(ctx, notificationID)
 	if err != nil {
 		return notification, err
 	}
@@ -787,16 +775,12 @@ func SetNotificationStatus(notificationID int64, user *user_model.User, status N
 
 	notification.Status = status
 
-	_, err = db.GetEngine(db.DefaultContext).ID(notificationID).Update(notification)
+	_, err = db.GetEngine(ctx).ID(notificationID).Update(notification)
 	return notification, err
 }
 
 // GetNotificationByID return notification by ID
-func GetNotificationByID(notificationID int64) (*Notification, error) {
-	return getNotificationByID(db.DefaultContext, notificationID)
-}
-
-func getNotificationByID(ctx context.Context, notificationID int64) (*Notification, error) {
+func GetNotificationByID(ctx context.Context, notificationID int64) (*Notification, error) {
 	notification := new(Notification)
 	ok, err := db.GetEngine(ctx).
 		Where("id = ?", notificationID).
@@ -813,9 +797,9 @@ func getNotificationByID(ctx context.Context, notificationID int64) (*Notificati
 }
 
 // UpdateNotificationStatuses updates the statuses of all of a user's notifications that are of the currentStatus type to the desiredStatus
-func UpdateNotificationStatuses(user *user_model.User, currentStatus, desiredStatus NotificationStatus) error {
+func UpdateNotificationStatuses(ctx context.Context, user *user_model.User, currentStatus, desiredStatus NotificationStatus) error {
 	n := &Notification{Status: desiredStatus, UpdatedBy: user.ID}
-	_, err := db.GetEngine(db.DefaultContext).
+	_, err := db.GetEngine(ctx).
 		Where("user_id = ? AND status = ?", user.ID, currentStatus).
 		Cols("status", "updated_by", "updated_unix").
 		Update(n)
diff --git a/models/activities/notification_test.go b/models/activities/notification_test.go
index 4ee16af07..d87189100 100644
--- a/models/activities/notification_test.go
+++ b/models/activities/notification_test.go
@@ -82,14 +82,14 @@ func TestSetNotificationStatus(t *testing.T) {
 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 	notf := unittest.AssertExistsAndLoadBean(t,
 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead})
-	_, err := activities_model.SetNotificationStatus(notf.ID, user, activities_model.NotificationStatusPinned)
+	_, err := activities_model.SetNotificationStatus(db.DefaultContext, notf.ID, user, activities_model.NotificationStatusPinned)
 	assert.NoError(t, err)
 	unittest.AssertExistsAndLoadBean(t,
 		&activities_model.Notification{ID: notf.ID, Status: activities_model.NotificationStatusPinned})
 
-	_, err = activities_model.SetNotificationStatus(1, user, activities_model.NotificationStatusRead)
+	_, err = activities_model.SetNotificationStatus(db.DefaultContext, 1, user, activities_model.NotificationStatusRead)
 	assert.Error(t, err)
-	_, err = activities_model.SetNotificationStatus(unittest.NonexistentID, user, activities_model.NotificationStatusRead)
+	_, err = activities_model.SetNotificationStatus(db.DefaultContext, unittest.NonexistentID, user, activities_model.NotificationStatusRead)
 	assert.Error(t, err)
 }
 
@@ -102,7 +102,7 @@ func TestUpdateNotificationStatuses(t *testing.T) {
 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead})
 	notfPinned := unittest.AssertExistsAndLoadBean(t,
 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusPinned})
-	assert.NoError(t, activities_model.UpdateNotificationStatuses(user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead))
+	assert.NoError(t, activities_model.UpdateNotificationStatuses(db.DefaultContext, user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead))
 	unittest.AssertExistsAndLoadBean(t,
 		&activities_model.Notification{ID: notfUnread.ID, Status: activities_model.NotificationStatusRead})
 	unittest.AssertExistsAndLoadBean(t,
diff --git a/models/db/consistency.go b/models/db/consistency.go
index 7addb174c..5a7878c74 100644
--- a/models/db/consistency.go
+++ b/models/db/consistency.go
@@ -4,11 +4,16 @@
 
 package db
 
-import "xorm.io/builder"
+import (
+	"context"
+
+	"xorm.io/builder"
+)
 
 // CountOrphanedObjects count subjects with have no existing refobject anymore
-func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
-	return GetEngine(DefaultContext).Table("`"+subject+"`").
+func CountOrphanedObjects(ctx context.Context, subject, refobject, joinCond string) (int64, error) {
+	return GetEngine(ctx).
+		Table("`"+subject+"`").
 		Join("LEFT", "`"+refobject+"`", joinCond).
 		Where(builder.IsNull{"`" + refobject + "`.id"}).
 		Select("COUNT(`" + subject + "`.`id`)").
@@ -16,12 +21,12 @@ func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
 }
 
 // DeleteOrphanedObjects delete subjects with have no existing refobject anymore
-func DeleteOrphanedObjects(subject, refobject, joinCond string) error {
+func DeleteOrphanedObjects(ctx context.Context, subject, refobject, joinCond string) error {
 	subQuery := builder.Select("`"+subject+"`.id").
 		From("`"+subject+"`").
 		Join("LEFT", "`"+refobject+"`", joinCond).
 		Where(builder.IsNull{"`" + refobject + "`.id"})
 	b := builder.Delete(builder.In("id", subQuery)).From("`" + subject + "`")
-	_, err := GetEngine(DefaultContext).Exec(b)
+	_, err := GetEngine(ctx).Exec(b)
 	return err
 }
diff --git a/models/db/engine_test.go b/models/db/engine_test.go
index c26d94c34..c2ba9614a 100644
--- a/models/db/engine_test.go
+++ b/models/db/engine_test.go
@@ -41,11 +41,11 @@ func TestDeleteOrphanedObjects(t *testing.T) {
 	_, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
 	assert.NoError(t, err)
 
-	orphaned, err := db.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
+	orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
 	assert.NoError(t, err)
 	assert.EqualValues(t, 3, orphaned)
 
-	err = db.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
+	err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
 	assert.NoError(t, err)
 
 	countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
diff --git a/models/db/sequence.go b/models/db/sequence.go
index 48e4a8f1a..0daacee70 100644
--- a/models/db/sequence.go
+++ b/models/db/sequence.go
@@ -5,6 +5,7 @@
 package db
 
 import (
+	"context"
 	"fmt"
 	"regexp"
 
@@ -12,7 +13,7 @@ import (
 )
 
 // CountBadSequences looks for broken sequences from recreate-table mistakes
-func CountBadSequences() (int64, error) {
+func CountBadSequences(_ context.Context) (int64, error) {
 	if !setting.Database.UsePostgreSQL {
 		return 0, nil
 	}
@@ -33,7 +34,7 @@ func CountBadSequences() (int64, error) {
 }
 
 // FixBadSequences fixes for broken sequences from recreate-table mistakes
-func FixBadSequences() error {
+func FixBadSequences(_ context.Context) error {
 	if !setting.Database.UsePostgreSQL {
 		return nil
 	}
diff --git a/models/fixture_generation.go b/models/fixture_generation.go
index f4644859e..50b983fa8 100644
--- a/models/fixture_generation.go
+++ b/models/fixture_generation.go
@@ -22,7 +22,7 @@ func GetYamlFixturesAccess() (string, error) {
 	}
 
 	for _, repo := range repos {
-		repo.MustOwner()
+		repo.MustOwner(db.DefaultContext)
 		if err := access_model.RecalculateAccesses(db.DefaultContext, repo); err != nil {
 			return "", err
 		}
diff --git a/models/git/protected_tag.go b/models/git/protected_tag.go
index 7c3881643..4640a77b2 100644
--- a/models/git/protected_tag.go
+++ b/models/git/protected_tag.go
@@ -5,6 +5,7 @@
 package git
 
 import (
+	"context"
 	"regexp"
 	"strings"
 
@@ -69,13 +70,13 @@ func UpdateProtectedTag(pt *ProtectedTag) error {
 }
 
 // DeleteProtectedTag deletes a protected tag by ID
-func DeleteProtectedTag(pt *ProtectedTag) error {
-	_, err := db.GetEngine(db.DefaultContext).ID(pt.ID).Delete(&ProtectedTag{})
+func DeleteProtectedTag(ctx context.Context, pt *ProtectedTag) error {
+	_, err := db.GetEngine(ctx).ID(pt.ID).Delete(&ProtectedTag{})
 	return err
 }
 
 // IsUserAllowedModifyTag returns true if the user is allowed to modify the tag
-func IsUserAllowedModifyTag(pt *ProtectedTag, userID int64) (bool, error) {
+func IsUserAllowedModifyTag(ctx context.Context, pt *ProtectedTag, userID int64) (bool, error) {
 	if base.Int64sContains(pt.AllowlistUserIDs, userID) {
 		return true, nil
 	}
@@ -84,7 +85,7 @@ func IsUserAllowedModifyTag(pt *ProtectedTag, userID int64) (bool, error) {
 		return false, nil
 	}
 
-	in, err := organization.IsUserInTeams(db.DefaultContext, userID, pt.AllowlistTeamIDs)
+	in, err := organization.IsUserInTeams(ctx, userID, pt.AllowlistTeamIDs)
 	if err != nil {
 		return false, err
 	}
@@ -92,9 +93,9 @@ func IsUserAllowedModifyTag(pt *ProtectedTag, userID int64) (bool, error) {
 }
 
 // GetProtectedTags gets all protected tags of the repository
-func GetProtectedTags(repoID int64) ([]*ProtectedTag, error) {
+func GetProtectedTags(ctx context.Context, repoID int64) ([]*ProtectedTag, error) {
 	tags := make([]*ProtectedTag, 0)
-	return tags, db.GetEngine(db.DefaultContext).Find(&tags, &ProtectedTag{RepoID: repoID})
+	return tags, db.GetEngine(ctx).Find(&tags, &ProtectedTag{RepoID: repoID})
 }
 
 // GetProtectedTagByID gets the protected tag with the specific id
@@ -112,7 +113,7 @@ func GetProtectedTagByID(id int64) (*ProtectedTag, error) {
 
 // IsUserAllowedToControlTag checks if a user can control the specific tag.
 // It returns true if the tag name is not protected or the user is allowed to control it.
-func IsUserAllowedToControlTag(tags []*ProtectedTag, tagName string, userID int64) (bool, error) {
+func IsUserAllowedToControlTag(ctx context.Context, tags []*ProtectedTag, tagName string, userID int64) (bool, error) {
 	isAllowed := true
 	for _, tag := range tags {
 		err := tag.EnsureCompiledPattern()
@@ -124,7 +125,7 @@ func IsUserAllowedToControlTag(tags []*ProtectedTag, tagName string, userID int6
 			continue
 		}
 
-		isAllowed, err = IsUserAllowedModifyTag(tag, userID)
+		isAllowed, err = IsUserAllowedModifyTag(ctx, tag, userID)
 		if err != nil {
 			return false, err
 		}
diff --git a/models/git/protected_tag_test.go b/models/git/protected_tag_test.go
index b496688b2..352eed006 100644
--- a/models/git/protected_tag_test.go
+++ b/models/git/protected_tag_test.go
@@ -7,6 +7,7 @@ package git_test
 import (
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	git_model "code.gitea.io/gitea/models/git"
 	"code.gitea.io/gitea/models/unittest"
 
@@ -17,29 +18,29 @@ func TestIsUserAllowed(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
 	pt := &git_model.ProtectedTag{}
-	allowed, err := git_model.IsUserAllowedModifyTag(pt, 1)
+	allowed, err := git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
 	assert.NoError(t, err)
 	assert.False(t, allowed)
 
 	pt = &git_model.ProtectedTag{
 		AllowlistUserIDs: []int64{1},
 	}
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
 	assert.NoError(t, err)
 	assert.True(t, allowed)
 
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
 	assert.NoError(t, err)
 	assert.False(t, allowed)
 
 	pt = &git_model.ProtectedTag{
 		AllowlistTeamIDs: []int64{1},
 	}
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
 	assert.NoError(t, err)
 	assert.False(t, allowed)
 
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
 	assert.NoError(t, err)
 	assert.True(t, allowed)
 
@@ -47,11 +48,11 @@ func TestIsUserAllowed(t *testing.T) {
 		AllowlistUserIDs: []int64{1},
 		AllowlistTeamIDs: []int64{1},
 	}
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 1)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
 	assert.NoError(t, err)
 	assert.True(t, allowed)
 
-	allowed, err = git_model.IsUserAllowedModifyTag(pt, 2)
+	allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
 	assert.NoError(t, err)
 	assert.True(t, allowed)
 }
@@ -135,7 +136,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
 		}
 
 		for n, c := range cases {
-			isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
+			isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid)
 			assert.NoError(t, err)
 			assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
 		}
@@ -157,7 +158,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
 		}
 
 		for n, c := range cases {
-			isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, c.name, c.userid)
+			isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid)
 			assert.NoError(t, err)
 			assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
 		}
diff --git a/models/issues/assignees.go b/models/issues/assignees.go
index ce497b116..19480fa1e 100644
--- a/models/issues/assignees.go
+++ b/models/issues/assignees.go
@@ -48,9 +48,10 @@ func (issue *Issue) LoadAssignees(ctx context.Context) (err error) {
 // GetAssigneeIDsByIssue returns the IDs of users assigned to an issue
 // but skips joining with `user` for performance reasons.
 // User permissions must be verified elsewhere if required.
-func GetAssigneeIDsByIssue(issueID int64) ([]int64, error) {
+func GetAssigneeIDsByIssue(ctx context.Context, issueID int64) ([]int64, error) {
 	userIDs := make([]int64, 0, 5)
-	return userIDs, db.GetEngine(db.DefaultContext).Table("issue_assignees").
+	return userIDs, db.GetEngine(ctx).
+		Table("issue_assignees").
 		Cols("assignee_id").
 		Where("issue_id = ?", issueID).
 		Distinct("assignee_id").
@@ -151,7 +152,7 @@ func toggleUserAssignee(ctx context.Context, issue *Issue, assigneeID int64) (re
 }
 
 // MakeIDsFromAPIAssigneesToAdd returns an array with all assignee IDs
-func MakeIDsFromAPIAssigneesToAdd(oneAssignee string, multipleAssignees []string) (assigneeIDs []int64, err error) {
+func MakeIDsFromAPIAssigneesToAdd(ctx context.Context, oneAssignee string, multipleAssignees []string) (assigneeIDs []int64, err error) {
 	var requestAssignees []string
 
 	// Keeping the old assigning method for compatibility reasons
@@ -165,7 +166,7 @@ func MakeIDsFromAPIAssigneesToAdd(oneAssignee string, multipleAssignees []string
 	}
 
 	// Get the IDs of all assignees
-	assigneeIDs, err = user_model.GetUserIDsByNames(requestAssignees, false)
+	assigneeIDs, err = user_model.GetUserIDsByNames(ctx, requestAssignees, false)
 
 	return assigneeIDs, err
 }
diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go
index 291bb673d..4286bdd7e 100644
--- a/models/issues/assignees_test.go
+++ b/models/issues/assignees_test.go
@@ -71,22 +71,22 @@ func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) {
 	_ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
 	_ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 
-	IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{""})
+	IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{""})
 	assert.NoError(t, err)
 	assert.Equal(t, []int64{}, IDs)
 
-	_, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"none_existing_user"})
+	_, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"none_existing_user"})
 	assert.Error(t, err)
 
-	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user1", []string{"user1"})
+	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user1", []string{"user1"})
 	assert.NoError(t, err)
 	assert.Equal(t, []int64{1}, IDs)
 
-	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user2", []string{""})
+	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user2", []string{""})
 	assert.NoError(t, err)
 	assert.Equal(t, []int64{2}, IDs)
 
-	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"user1", "user2"})
+	IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"user1", "user2"})
 	assert.NoError(t, err)
 	assert.Equal(t, []int64{1, 2}, IDs)
 }
diff --git a/models/issues/comment.go b/models/issues/comment.go
index d71c675d2..9483814a1 100644
--- a/models/issues/comment.go
+++ b/models/issues/comment.go
@@ -309,13 +309,8 @@ type PushActionContent struct {
 	CommitIDs   []string `json:"commit_ids"`
 }
 
-// LoadIssue loads issue from database
-func (c *Comment) LoadIssue() (err error) {
-	return c.LoadIssueCtx(db.DefaultContext)
-}
-
-// LoadIssueCtx loads issue from database
-func (c *Comment) LoadIssueCtx(ctx context.Context) (err error) {
+// LoadIssue loads the issue reference for the comment
+func (c *Comment) LoadIssue(ctx context.Context) (err error) {
 	if c.Issue != nil {
 		return nil
 	}
@@ -350,7 +345,8 @@ func (c *Comment) AfterLoad(session *xorm.Session) {
 	}
 }
 
-func (c *Comment) loadPoster(ctx context.Context) (err error) {
+// LoadPoster loads comment poster
+func (c *Comment) LoadPoster(ctx context.Context) (err error) {
 	if c.PosterID <= 0 || c.Poster != nil {
 		return nil
 	}
@@ -381,7 +377,7 @@ func (c *Comment) AfterDelete() {
 
 // HTMLURL formats a URL-string to the issue-comment
 func (c *Comment) HTMLURL() string {
-	err := c.LoadIssue()
+	err := c.LoadIssue(db.DefaultContext)
 	if err != nil { // Silently dropping errors :unamused:
 		log.Error("LoadIssue(%d): %v", c.IssueID, err)
 		return ""
@@ -410,7 +406,7 @@ func (c *Comment) HTMLURL() string {
 
 // APIURL formats a API-string to the issue-comment
 func (c *Comment) APIURL() string {
-	err := c.LoadIssue()
+	err := c.LoadIssue(db.DefaultContext)
 	if err != nil { // Silently dropping errors :unamused:
 		log.Error("LoadIssue(%d): %v", c.IssueID, err)
 		return ""
@@ -426,7 +422,7 @@ func (c *Comment) APIURL() string {
 
 // IssueURL formats a URL-string to the issue
 func (c *Comment) IssueURL() string {
-	err := c.LoadIssue()
+	err := c.LoadIssue(db.DefaultContext)
 	if err != nil { // Silently dropping errors :unamused:
 		log.Error("LoadIssue(%d): %v", c.IssueID, err)
 		return ""
@@ -446,7 +442,7 @@ func (c *Comment) IssueURL() string {
 
 // PRURL formats a URL-string to the pull-request
 func (c *Comment) PRURL() string {
-	err := c.LoadIssue()
+	err := c.LoadIssue(db.DefaultContext)
 	if err != nil { // Silently dropping errors :unamused:
 		log.Error("LoadIssue(%d): %v", c.IssueID, err)
 		return ""
@@ -521,10 +517,10 @@ func (c *Comment) LoadProject() error {
 }
 
 // LoadMilestone if comment.Type is CommentTypeMilestone, then load milestone
-func (c *Comment) LoadMilestone() error {
+func (c *Comment) LoadMilestone(ctx context.Context) error {
 	if c.OldMilestoneID > 0 {
 		var oldMilestone Milestone
-		has, err := db.GetEngine(db.DefaultContext).ID(c.OldMilestoneID).Get(&oldMilestone)
+		has, err := db.GetEngine(ctx).ID(c.OldMilestoneID).Get(&oldMilestone)
 		if err != nil {
 			return err
 		} else if has {
@@ -534,7 +530,7 @@ func (c *Comment) LoadMilestone() error {
 
 	if c.MilestoneID > 0 {
 		var milestone Milestone
-		has, err := db.GetEngine(db.DefaultContext).ID(c.MilestoneID).Get(&milestone)
+		has, err := db.GetEngine(ctx).ID(c.MilestoneID).Get(&milestone)
 		if err != nil {
 			return err
 		} else if has {
@@ -544,19 +540,14 @@ func (c *Comment) LoadMilestone() error {
 	return nil
 }
 
-// LoadPoster loads comment poster
-func (c *Comment) LoadPoster() error {
-	return c.loadPoster(db.DefaultContext)
-}
-
 // LoadAttachments loads attachments (it never returns error, the error during `GetAttachmentsByCommentIDCtx` is ignored)
-func (c *Comment) LoadAttachments() error {
+func (c *Comment) LoadAttachments(ctx context.Context) error {
 	if len(c.Attachments) > 0 {
 		return nil
 	}
 
 	var err error
-	c.Attachments, err = repo_model.GetAttachmentsByCommentID(db.DefaultContext, c.ID)
+	c.Attachments, err = repo_model.GetAttachmentsByCommentID(ctx, c.ID)
 	if err != nil {
 		log.Error("getAttachmentsByCommentID[%d]: %v", c.ID, err)
 	}
@@ -598,7 +589,7 @@ func (c *Comment) LoadAssigneeUserAndTeam() error {
 			c.Assignee = user_model.NewGhostUser()
 		}
 	} else if c.AssigneeTeamID > 0 && c.AssigneeTeam == nil {
-		if err = c.LoadIssue(); err != nil {
+		if err = c.LoadIssue(db.DefaultContext); err != nil {
 			return err
 		}
 
@@ -740,7 +731,7 @@ func (c *Comment) UnsignedLine() uint64 {
 
 // CodeCommentURL returns the url to a comment in code
 func (c *Comment) CodeCommentURL() string {
-	err := c.LoadIssue()
+	err := c.LoadIssue(db.DefaultContext)
 	if err != nil { // Silently dropping errors :unamused:
 		log.Error("LoadIssue(%d): %v", c.IssueID, err)
 		return ""
@@ -1145,7 +1136,7 @@ func UpdateComment(c *Comment, doer *user_model.User) error {
 	if _, err := sess.ID(c.ID).AllCols().Update(c); err != nil {
 		return err
 	}
-	if err := c.LoadIssueCtx(ctx); err != nil {
+	if err := c.LoadIssue(ctx); err != nil {
 		return err
 	}
 	if err := c.AddCrossReferences(ctx, doer, true); err != nil {
@@ -1245,7 +1236,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
 		return nil, err
 	}
 
-	if err := CommentList(comments).loadPosters(ctx); err != nil {
+	if err := CommentList(comments).LoadPosters(ctx); err != nil {
 		return nil, err
 	}
 
@@ -1363,11 +1354,11 @@ func CreateAutoMergeComment(ctx context.Context, typ CommentType, pr *PullReques
 	if typ != CommentTypePRScheduledToAutoMerge && typ != CommentTypePRUnScheduledToAutoMerge {
 		return nil, fmt.Errorf("comment type %d cannot be used to create an auto merge comment", typ)
 	}
-	if err = pr.LoadIssueCtx(ctx); err != nil {
+	if err = pr.LoadIssue(ctx); err != nil {
 		return
 	}
 
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		return
 	}
 
@@ -1512,18 +1503,18 @@ func (c *Comment) GetExternalName() string { return c.OriginalAuthor }
 func (c *Comment) GetExternalID() int64 { return c.OriginalAuthorID }
 
 // CountCommentTypeLabelWithEmptyLabel count label comments with empty label
-func CountCommentTypeLabelWithEmptyLabel() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment))
+func CountCommentTypeLabelWithEmptyLabel(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment))
 }
 
 // FixCommentTypeLabelWithEmptyLabel count label comments with empty label
-func FixCommentTypeLabelWithEmptyLabel() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment))
+func FixCommentTypeLabelWithEmptyLabel(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment))
 }
 
 // CountCommentTypeLabelWithOutsideLabels count label comments with outside label
-func CountCommentTypeLabelWithOutsideLabels() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel).
+func CountCommentTypeLabelWithOutsideLabels(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel).
 		Table("comment").
 		Join("inner", "label", "label.id = comment.label_id").
 		Join("inner", "issue", "issue.id = comment.issue_id ").
@@ -1532,8 +1523,8 @@ func CountCommentTypeLabelWithOutsideLabels() (int64, error) {
 }
 
 // FixCommentTypeLabelWithOutsideLabels count label comments with outside label
-func FixCommentTypeLabelWithOutsideLabels() (int64, error) {
-	res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM comment WHERE comment.id IN (
+func FixCommentTypeLabelWithOutsideLabels(ctx context.Context) (int64, error) {
+	res, err := db.GetEngine(ctx).Exec(`DELETE FROM comment WHERE comment.id IN (
 		SELECT il_too.id FROM (
 			SELECT com.id
 				FROM comment AS com
diff --git a/models/issues/comment_list.go b/models/issues/comment_list.go
index 70105d7ff..e42b8605f 100644
--- a/models/issues/comment_list.go
+++ b/models/issues/comment_list.go
@@ -24,7 +24,8 @@ func (comments CommentList) getPosterIDs() []int64 {
 	return posterIDs.Values()
 }
 
-func (comments CommentList) loadPosters(ctx context.Context) error {
+// LoadPosters loads posters
+func (comments CommentList) LoadPosters(ctx context.Context) error {
 	if len(comments) == 0 {
 		return nil
 	}
@@ -277,7 +278,8 @@ func (comments CommentList) Issues() IssueList {
 	return issueList
 }
 
-func (comments CommentList) loadIssues(ctx context.Context) error {
+// LoadIssues loads issues of comments
+func (comments CommentList) LoadIssues(ctx context.Context) error {
 	if len(comments) == 0 {
 		return nil
 	}
@@ -382,7 +384,8 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error {
 	return nil
 }
 
-func (comments CommentList) loadAttachments(ctx context.Context) (err error) {
+// LoadAttachments loads attachments
+func (comments CommentList) LoadAttachments(ctx context.Context) (err error) {
 	if len(comments) == 0 {
 		return nil
 	}
@@ -476,7 +479,7 @@ func (comments CommentList) loadReviews(ctx context.Context) error { //nolint
 
 // loadAttributes loads all attributes
 func (comments CommentList) loadAttributes(ctx context.Context) (err error) {
-	if err = comments.loadPosters(ctx); err != nil {
+	if err = comments.LoadPosters(ctx); err != nil {
 		return
 	}
 
@@ -496,7 +499,7 @@ func (comments CommentList) loadAttributes(ctx context.Context) (err error) {
 		return
 	}
 
-	if err = comments.loadAttachments(ctx); err != nil {
+	if err = comments.LoadAttachments(ctx); err != nil {
 		return
 	}
 
@@ -504,7 +507,7 @@ func (comments CommentList) loadAttributes(ctx context.Context) (err error) {
 		return
 	}
 
-	if err = comments.loadIssues(ctx); err != nil {
+	if err = comments.LoadIssues(ctx); err != nil {
 		return
 	}
 
@@ -520,18 +523,3 @@ func (comments CommentList) loadAttributes(ctx context.Context) (err error) {
 func (comments CommentList) LoadAttributes() error {
 	return comments.loadAttributes(db.DefaultContext)
 }
-
-// LoadAttachments loads attachments
-func (comments CommentList) LoadAttachments() error {
-	return comments.loadAttachments(db.DefaultContext)
-}
-
-// LoadPosters loads posters
-func (comments CommentList) LoadPosters() error {
-	return comments.loadPosters(db.DefaultContext)
-}
-
-// LoadIssues loads issues of comments
-func (comments CommentList) LoadIssues() error {
-	return comments.loadIssues(db.DefaultContext)
-}
diff --git a/models/issues/issue.go b/models/issues/issue.go
index c2f7cb657..69d6657d4 100644
--- a/models/issues/issue.go
+++ b/models/issues/issue.go
@@ -241,11 +241,7 @@ func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
 }
 
 // LoadPoster loads poster
-func (issue *Issue) LoadPoster() error {
-	return issue.loadPoster(db.DefaultContext)
-}
-
-func (issue *Issue) loadPoster(ctx context.Context) (err error) {
+func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
 	if issue.Poster == nil {
 		issue.Poster, err = user_model.GetUserByIDCtx(ctx, issue.PosterID)
 		if err != nil {
@@ -261,7 +257,8 @@ func (issue *Issue) loadPoster(ctx context.Context) (err error) {
 	return err
 }
 
-func (issue *Issue) loadPullRequest(ctx context.Context) (err error) {
+// LoadPullRequest loads pull request info
+func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) {
 	if issue.IsPull && issue.PullRequest == nil {
 		issue.PullRequest, err = GetPullRequestByIssueID(ctx, issue.ID)
 		if err != nil {
@@ -275,18 +272,13 @@ func (issue *Issue) loadPullRequest(ctx context.Context) (err error) {
 	return nil
 }
 
-// LoadPullRequest loads pull request info
-func (issue *Issue) LoadPullRequest() error {
-	return issue.loadPullRequest(db.DefaultContext)
-}
-
 func (issue *Issue) loadComments(ctx context.Context) (err error) {
 	return issue.loadCommentsByType(ctx, CommentTypeUnknown)
 }
 
 // LoadDiscussComments loads discuss comments
-func (issue *Issue) LoadDiscussComments() error {
-	return issue.loadCommentsByType(db.DefaultContext, CommentTypeComment)
+func (issue *Issue) LoadDiscussComments(ctx context.Context) error {
+	return issue.loadCommentsByType(ctx, CommentTypeComment)
 }
 
 func (issue *Issue) loadCommentsByType(ctx context.Context, tp CommentType) (err error) {
@@ -357,7 +349,8 @@ func (issue *Issue) loadForeignReference(ctx context.Context) (err error) {
 	return nil
 }
 
-func (issue *Issue) loadMilestone(ctx context.Context) (err error) {
+// LoadMilestone load milestone of this issue.
+func (issue *Issue) LoadMilestone(ctx context.Context) (err error) {
 	if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
 		issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID)
 		if err != nil && !IsErrMilestoneNotExist(err) {
@@ -373,7 +366,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
 		return
 	}
 
-	if err = issue.loadPoster(ctx); err != nil {
+	if err = issue.LoadPoster(ctx); err != nil {
 		return
 	}
 
@@ -381,7 +374,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
 		return
 	}
 
-	if err = issue.loadMilestone(ctx); err != nil {
+	if err = issue.LoadMilestone(ctx); err != nil {
 		return
 	}
 
@@ -393,7 +386,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
 		return
 	}
 
-	if err = issue.loadPullRequest(ctx); err != nil && !IsErrPullRequestNotExist(err) {
+	if err = issue.LoadPullRequest(ctx); err != nil && !IsErrPullRequestNotExist(err) {
 		// It is possible pull request is not yet created.
 		return err
 	}
@@ -425,11 +418,6 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
 	return issue.loadReactions(ctx)
 }
 
-// LoadMilestone load milestone of this issue.
-func (issue *Issue) LoadMilestone() error {
-	return issue.loadMilestone(db.DefaultContext)
-}
-
 // GetIsRead load the `IsRead` field of the issue
 func (issue *Issue) GetIsRead(userID int64) error {
 	issueUser := &IssueUser{IssueID: issue.ID, UID: userID}
@@ -548,7 +536,7 @@ func ClearIssueLabels(issue *Issue, doer *user_model.User) (err error) {
 
 	if err := issue.LoadRepo(ctx); err != nil {
 		return err
-	} else if err = issue.loadPullRequest(ctx); err != nil {
+	} else if err = issue.LoadPullRequest(ctx); err != nil {
 		return err
 	}
 
@@ -751,7 +739,7 @@ func ChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User,
 	if err := issue.LoadRepo(ctx); err != nil {
 		return nil, err
 	}
-	if err := issue.loadPoster(ctx); err != nil {
+	if err := issue.LoadPoster(ctx); err != nil {
 		return nil, err
 	}
 
@@ -1027,7 +1015,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
 			return fmt.Errorf("find all labels [label_ids: %v]: %w", opts.LabelIDs, err)
 		}
 
-		if err = opts.Issue.loadPoster(ctx); err != nil {
+		if err = opts.Issue.LoadPoster(ctx); err != nil {
 			return err
 		}
 
@@ -1505,10 +1493,9 @@ func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Sess
 }
 
 // CountIssuesByRepo map from repoID to number of issues matching the options
-func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
-	e := db.GetEngine(db.DefaultContext)
-
-	sess := e.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
+func CountIssuesByRepo(ctx context.Context, opts *IssuesOptions) (map[int64]int64, error) {
+	sess := db.GetEngine(ctx).
+		Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
 
 	opts.setupSessionNoLimit(sess)
 
@@ -1551,10 +1538,9 @@ func GetRepoIDsForIssuesOptions(opts *IssuesOptions, user *user_model.User) ([]i
 }
 
 // Issues returns a list of issues by given conditions.
-func Issues(opts *IssuesOptions) ([]*Issue, error) {
-	e := db.GetEngine(db.DefaultContext)
-
-	sess := e.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
+func Issues(ctx context.Context, opts *IssuesOptions) ([]*Issue, error) {
+	sess := db.GetEngine(ctx).
+		Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
 	opts.setupSessionWithLimit(sess)
 
 	sortIssuesSession(sess, opts.SortType, opts.PriorityRepoID)
@@ -1572,11 +1558,11 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
 }
 
 // CountIssues number return of issues by given conditions.
-func CountIssues(opts *IssuesOptions) (int64, error) {
-	e := db.GetEngine(db.DefaultContext)
-
-	sess := e.Select("COUNT(issue.id) AS count").Table("issue")
-	sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
+func CountIssues(ctx context.Context, opts *IssuesOptions) (int64, error) {
+	sess := db.GetEngine(ctx).
+		Select("COUNT(issue.id) AS count").
+		Table("issue").
+		Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
 	opts.setupSessionNoLimit(sess)
 
 	return sess.Count()
@@ -1585,9 +1571,10 @@ func CountIssues(opts *IssuesOptions) (int64, error) {
 // GetParticipantsIDsByIssueID returns the IDs of all users who participated in comments of an issue,
 // but skips joining with `user` for performance reasons.
 // User permissions must be verified elsewhere if required.
-func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) {
+func GetParticipantsIDsByIssueID(ctx context.Context, issueID int64) ([]int64, error) {
 	userIDs := make([]int64, 0, 5)
-	return userIDs, db.GetEngine(db.DefaultContext).Table("comment").
+	return userIDs, db.GetEngine(ctx).
+		Table("comment").
 		Cols("poster_id").
 		Where("issue_id = ?", issueID).
 		And("type in (?,?,?)", CommentTypeComment, CommentTypeCode, CommentTypeReview).
@@ -2426,8 +2413,9 @@ func (issue *Issue) GetExternalName() string { return issue.OriginalAuthor }
 func (issue *Issue) GetExternalID() int64 { return issue.OriginalAuthorID }
 
 // CountOrphanedIssues count issues without a repo
-func CountOrphanedIssues() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Table("issue").
+func CountOrphanedIssues(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).
+		Table("issue").
 		Join("LEFT", "repository", "issue.repo_id=repository.id").
 		Where(builder.IsNull{"repository.id"}).
 		Select("COUNT(`issue`.`id`)").
@@ -2435,35 +2423,31 @@ func CountOrphanedIssues() (int64, error) {
 }
 
 // DeleteOrphanedIssues delete issues without a repo
-func DeleteOrphanedIssues() error {
-	ctx, committer, err := db.TxContext(db.DefaultContext)
+func DeleteOrphanedIssues(ctx context.Context) error {
+	var attachmentPaths []string
+	err := db.AutoTx(ctx, func(ctx context.Context) error {
+		var ids []int64
+
+		if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id").
+			Join("LEFT", "repository", "issue.repo_id=repository.id").
+			Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id").
+			Find(&ids); err != nil {
+			return err
+		}
+
+		for i := range ids {
+			paths, err := DeleteIssuesByRepoID(ctx, ids[i])
+			if err != nil {
+				return err
+			}
+			attachmentPaths = append(attachmentPaths, paths...)
+		}
+
+		return nil
+	})
 	if err != nil {
 		return err
 	}
-	defer committer.Close()
-
-	var ids []int64
-
-	if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id").
-		Join("LEFT", "repository", "issue.repo_id=repository.id").
-		Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id").
-		Find(&ids); err != nil {
-		return err
-	}
-
-	var attachmentPaths []string
-	for i := range ids {
-		paths, err := DeleteIssuesByRepoID(ctx, ids[i])
-		if err != nil {
-			return err
-		}
-		attachmentPaths = append(attachmentPaths, paths...)
-	}
-
-	if err := committer.Commit(); err != nil {
-		return err
-	}
-	committer.Close()
 
 	// Remove issue attachment files.
 	for i := range attachmentPaths {
diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go
index bbe2292dd..d9dff4cb4 100644
--- a/models/issues/issue_list.go
+++ b/models/issues/issue_list.go
@@ -34,7 +34,8 @@ func (issues IssueList) getRepoIDs() []int64 {
 	return repoIDs.Values()
 }
 
-func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) {
+// LoadRepositories loads issues' all repositories
+func (issues IssueList) LoadRepositories(ctx context.Context) ([]*repo_model.Repository, error) {
 	if len(issues) == 0 {
 		return nil, nil
 	}
@@ -73,11 +74,6 @@ func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Rep
 	return repo_model.ValuesRepository(repoMaps), nil
 }
 
-// LoadRepositories loads issues' all repositories
-func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) {
-	return issues.loadRepositories(db.DefaultContext)
-}
-
 func (issues IssueList) getPosterIDs() []int64 {
 	posterIDs := make(container.Set[int64], len(issues))
 	for _, issue := range issues {
@@ -317,7 +313,8 @@ func (issues IssueList) getPullIssueIDs() []int64 {
 	return ids
 }
 
-func (issues IssueList) loadPullRequests(ctx context.Context) error {
+// LoadPullRequests loads pull requests
+func (issues IssueList) LoadPullRequests(ctx context.Context) error {
 	issuesIDs := issues.getPullIssueIDs()
 	if len(issuesIDs) == 0 {
 		return nil
@@ -361,7 +358,8 @@ func (issues IssueList) loadPullRequests(ctx context.Context) error {
 	return nil
 }
 
-func (issues IssueList) loadAttachments(ctx context.Context) (err error) {
+// LoadAttachments loads attachments
+func (issues IssueList) LoadAttachments(ctx context.Context) (err error) {
 	if len(issues) == 0 {
 		return nil
 	}
@@ -513,8 +511,8 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) {
 
 // loadAttributes loads all attributes, expect for attachments and comments
 func (issues IssueList) loadAttributes(ctx context.Context) error {
-	if _, err := issues.loadRepositories(ctx); err != nil {
-		return fmt.Errorf("issue.loadAttributes: loadRepositories: %w", err)
+	if _, err := issues.LoadRepositories(ctx); err != nil {
+		return fmt.Errorf("issue.loadAttributes: LoadRepositories: %w", err)
 	}
 
 	if err := issues.loadPosters(ctx); err != nil {
@@ -537,7 +535,7 @@ func (issues IssueList) loadAttributes(ctx context.Context) error {
 		return fmt.Errorf("issue.loadAttributes: loadAssignees: %w", err)
 	}
 
-	if err := issues.loadPullRequests(ctx); err != nil {
+	if err := issues.LoadPullRequests(ctx); err != nil {
 		return fmt.Errorf("issue.loadAttributes: loadPullRequests: %w", err)
 	}
 
@@ -554,24 +552,14 @@ func (issues IssueList) LoadAttributes() error {
 	return issues.loadAttributes(db.DefaultContext)
 }
 
-// LoadAttachments loads attachments
-func (issues IssueList) LoadAttachments() error {
-	return issues.loadAttachments(db.DefaultContext)
-}
-
 // LoadComments loads comments
-func (issues IssueList) LoadComments() error {
-	return issues.loadComments(db.DefaultContext, builder.NewCond())
+func (issues IssueList) LoadComments(ctx context.Context) error {
+	return issues.loadComments(ctx, builder.NewCond())
 }
 
 // LoadDiscussComments loads discuss comments
-func (issues IssueList) LoadDiscussComments() error {
-	return issues.loadComments(db.DefaultContext, builder.Eq{"comment.type": CommentTypeComment})
-}
-
-// LoadPullRequests loads pull requests
-func (issues IssueList) LoadPullRequests() error {
-	return issues.loadPullRequests(db.DefaultContext)
+func (issues IssueList) LoadDiscussComments(ctx context.Context) error {
+	return issues.loadComments(ctx, builder.Eq{"comment.type": CommentTypeComment})
 }
 
 // GetApprovalCounts returns a map of issue ID to slice of approval counts
diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go
index f2cfca9bc..c38a405e0 100644
--- a/models/issues/issue_list_test.go
+++ b/models/issues/issue_list_test.go
@@ -7,6 +7,7 @@ package issues_test
 import (
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	"code.gitea.io/gitea/models/unittest"
 	"code.gitea.io/gitea/modules/setting"
@@ -23,7 +24,7 @@ func TestIssueList_LoadRepositories(t *testing.T) {
 		unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}),
 	}
 
-	repos, err := issueList.LoadRepositories()
+	repos, err := issueList.LoadRepositories(db.DefaultContext)
 	assert.NoError(t, err)
 	assert.Len(t, repos, 2)
 	for _, issue := range issueList {
diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go
index 0c59f4e82..39a27abd3 100644
--- a/models/issues/issue_project.go
+++ b/models/issues/issue_project.go
@@ -61,11 +61,11 @@ func (issue *Issue) projectBoardID(ctx context.Context) int64 {
 }
 
 // LoadIssuesFromBoard load issues assigned to this board
-func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) {
+func LoadIssuesFromBoard(ctx context.Context, b *project_model.Board) (IssueList, error) {
 	issueList := make([]*Issue, 0, 10)
 
 	if b.ID != 0 {
-		issues, err := Issues(&IssuesOptions{
+		issues, err := Issues(ctx, &IssuesOptions{
 			ProjectBoardID: b.ID,
 			ProjectID:      b.ProjectID,
 			SortType:       "project-column-sorting",
@@ -77,7 +77,7 @@ func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) {
 	}
 
 	if b.Default {
-		issues, err := Issues(&IssuesOptions{
+		issues, err := Issues(ctx, &IssuesOptions{
 			ProjectBoardID: -1, // Issues without ProjectBoardID
 			ProjectID:      b.ProjectID,
 			SortType:       "project-column-sorting",
@@ -88,7 +88,7 @@ func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) {
 		issueList = append(issueList, issues...)
 	}
 
-	if err := IssueList(issueList).LoadComments(); err != nil {
+	if err := IssueList(issueList).LoadComments(ctx); err != nil {
 		return nil, err
 	}
 
@@ -96,10 +96,10 @@ func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) {
 }
 
 // LoadIssuesFromBoardList load issues assigned to the boards
-func LoadIssuesFromBoardList(bs project_model.BoardList) (map[int64]IssueList, error) {
+func LoadIssuesFromBoardList(ctx context.Context, bs project_model.BoardList) (map[int64]IssueList, error) {
 	issuesMap := make(map[int64]IssueList, len(bs))
 	for i := range bs {
-		il, err := LoadIssuesFromBoard(bs[i])
+		il, err := LoadIssuesFromBoard(ctx, bs[i])
 		if err != nil {
 			return nil, err
 		}
diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go
index bef5d03e8..2c8728e71 100644
--- a/models/issues/issue_test.go
+++ b/models/issues/issue_test.go
@@ -189,7 +189,7 @@ func TestIssues(t *testing.T) {
 			[]int64{}, // issues with **both** label 1 and 2, none of these issues matches, TODO: add more tests
 		},
 	} {
-		issues, err := issues_model.Issues(&test.Opts)
+		issues, err := issues_model.Issues(db.DefaultContext, &test.Opts)
 		assert.NoError(t, err)
 		if assert.Len(t, issues, len(test.ExpectedIssueIDs)) {
 			for i, issue := range issues {
@@ -556,7 +556,7 @@ func TestLoadTotalTrackedTime(t *testing.T) {
 
 func TestCountIssues(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
-	count, err := issues_model.CountIssues(&issues_model.IssuesOptions{})
+	count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{})
 	assert.NoError(t, err)
 	assert.EqualValues(t, 17, count)
 }
diff --git a/models/issues/issue_xref.go b/models/issues/issue_xref.go
index e389f63d7..4c6601a0a 100644
--- a/models/issues/issue_xref.go
+++ b/models/issues/issue_xref.go
@@ -235,7 +235,7 @@ func (c *Comment) AddCrossReferences(stdCtx context.Context, doer *user_model.Us
 	if c.Type != CommentTypeCode && c.Type != CommentTypeComment {
 		return nil
 	}
-	if err := c.LoadIssueCtx(stdCtx); err != nil {
+	if err := c.LoadIssue(stdCtx); err != nil {
 		return err
 	}
 	ctx := &crossReferencesContext{
diff --git a/models/issues/label.go b/models/issues/label.go
index 0b0d1419b..dc7058d64 100644
--- a/models/issues/label.go
+++ b/models/issues/label.go
@@ -116,8 +116,8 @@ func (label *Label) CalOpenIssues() {
 }
 
 // CalOpenOrgIssues calculates the open issues of a label for a specific repo
-func (label *Label) CalOpenOrgIssues(repoID, labelID int64) {
-	counts, _ := CountIssuesByRepo(&IssuesOptions{
+func (label *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
+	counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{
 		RepoID:   repoID,
 		LabelIDs: []int64{labelID},
 		IsClosed: util.OptionalBoolFalse,
@@ -395,9 +395,9 @@ func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
 
 // GetLabelsInRepoByIDs returns a list of labels by IDs in given repository,
 // it silently ignores label IDs that do not belong to the repository.
-func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
+func GetLabelsInRepoByIDs(ctx context.Context, repoID int64, labelIDs []int64) ([]*Label, error) {
 	labels := make([]*Label, 0, len(labelIDs))
-	return labels, db.GetEngine(db.DefaultContext).
+	return labels, db.GetEngine(ctx).
 		Where("repo_id = ?", repoID).
 		In("id", labelIDs).
 		Asc("name").
@@ -498,9 +498,9 @@ func GetLabelIDsInOrgByNames(orgID int64, labelNames []string) ([]int64, error)
 
 // GetLabelsInOrgByIDs returns a list of labels by IDs in given organization,
 // it silently ignores label IDs that do not belong to the organization.
-func GetLabelsInOrgByIDs(orgID int64, labelIDs []int64) ([]*Label, error) {
+func GetLabelsInOrgByIDs(ctx context.Context, orgID int64, labelIDs []int64) ([]*Label, error) {
 	labels := make([]*Label, 0, len(labelIDs))
-	return labels, db.GetEngine(db.DefaultContext).
+	return labels, db.GetEngine(ctx).
 		Where("org_id = ?", orgID).
 		In("id", labelIDs).
 		Asc("name").
@@ -746,13 +746,13 @@ func DeleteLabelsByRepoID(ctx context.Context, repoID int64) error {
 }
 
 // CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore
-func CountOrphanedLabels() (int64, error) {
-	noref, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count()
+func CountOrphanedLabels(ctx context.Context) (int64, error) {
+	noref, err := db.GetEngine(ctx).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count()
 	if err != nil {
 		return 0, err
 	}
 
-	norepo, err := db.GetEngine(db.DefaultContext).Table("label").
+	norepo, err := db.GetEngine(ctx).Table("label").
 		Where(builder.And(
 			builder.Gt{"repo_id": 0},
 			builder.NotIn("repo_id", builder.Select("id").From("repository")),
@@ -762,7 +762,7 @@ func CountOrphanedLabels() (int64, error) {
 		return 0, err
 	}
 
-	noorg, err := db.GetEngine(db.DefaultContext).Table("label").
+	noorg, err := db.GetEngine(ctx).Table("label").
 		Where(builder.And(
 			builder.Gt{"org_id": 0},
 			builder.NotIn("org_id", builder.Select("id").From("user")),
@@ -776,14 +776,14 @@ func CountOrphanedLabels() (int64, error) {
 }
 
 // DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore
-func DeleteOrphanedLabels() error {
+func DeleteOrphanedLabels(ctx context.Context) error {
 	// delete labels with no reference
-	if _, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil {
+	if _, err := db.GetEngine(ctx).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil {
 		return err
 	}
 
 	// delete labels with none existing repos
-	if _, err := db.GetEngine(db.DefaultContext).
+	if _, err := db.GetEngine(ctx).
 		Where(builder.And(
 			builder.Gt{"repo_id": 0},
 			builder.NotIn("repo_id", builder.Select("id").From("repository")),
@@ -793,7 +793,7 @@ func DeleteOrphanedLabels() error {
 	}
 
 	// delete labels with none existing orgs
-	if _, err := db.GetEngine(db.DefaultContext).
+	if _, err := db.GetEngine(ctx).
 		Where(builder.And(
 			builder.Gt{"org_id": 0},
 			builder.NotIn("org_id", builder.Select("id").From("user")),
@@ -806,23 +806,23 @@ func DeleteOrphanedLabels() error {
 }
 
 // CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore
-func CountOrphanedIssueLabels() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Table("issue_label").
+func CountOrphanedIssueLabels(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Table("issue_label").
 		NotIn("label_id", builder.Select("id").From("label")).
 		Count()
 }
 
 // DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore
-func DeleteOrphanedIssueLabels() error {
-	_, err := db.GetEngine(db.DefaultContext).
+func DeleteOrphanedIssueLabels(ctx context.Context) error {
+	_, err := db.GetEngine(ctx).
 		NotIn("label_id", builder.Select("id").From("label")).
 		Delete(IssueLabel{})
 	return err
 }
 
 // CountIssueLabelWithOutsideLabels count label comments with outside label
-func CountIssueLabelWithOutsideLabels() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")).
+func CountIssueLabelWithOutsideLabels(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")).
 		Table("issue_label").
 		Join("inner", "label", "issue_label.label_id = label.id ").
 		Join("inner", "issue", "issue.id = issue_label.issue_id ").
@@ -831,8 +831,8 @@ func CountIssueLabelWithOutsideLabels() (int64, error) {
 }
 
 // FixIssueLabelWithOutsideLabels fix label comments with outside label
-func FixIssueLabelWithOutsideLabels() (int64, error) {
-	res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM issue_label WHERE issue_label.id IN (
+func FixIssueLabelWithOutsideLabels(ctx context.Context) (int64, error) {
+	res, err := db.GetEngine(ctx).Exec(`DELETE FROM issue_label WHERE issue_label.id IN (
 		SELECT il_too.id FROM (
 			SELECT il_too_too.id
 				FROM issue_label AS il_too_too
diff --git a/models/issues/label_test.go b/models/issues/label_test.go
index 5e6cc9a2a..077e0eeb6 100644
--- a/models/issues/label_test.go
+++ b/models/issues/label_test.go
@@ -121,7 +121,7 @@ func TestGetLabelInRepoByID(t *testing.T) {
 
 func TestGetLabelsInRepoByIDs(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
-	labels, err := issues_model.GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID})
+	labels, err := issues_model.GetLabelsInRepoByIDs(db.DefaultContext, 1, []int64{1, 2, unittest.NonexistentID})
 	assert.NoError(t, err)
 	if assert.Len(t, labels, 2) {
 		assert.EqualValues(t, 1, labels[0].ID)
@@ -212,7 +212,7 @@ func TestGetLabelInOrgByID(t *testing.T) {
 
 func TestGetLabelsInOrgByIDs(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
-	labels, err := issues_model.GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID})
+	labels, err := issues_model.GetLabelsInOrgByIDs(db.DefaultContext, 3, []int64{3, 4, unittest.NonexistentID})
 	assert.NoError(t, err)
 	if assert.Len(t, labels, 2) {
 		assert.EqualValues(t, 3, labels[0].ID)
diff --git a/models/issues/pull.go b/models/issues/pull.go
index e906407d3..993a1ba8b 100644
--- a/models/issues/pull.go
+++ b/models/issues/pull.go
@@ -205,8 +205,8 @@ func DeletePullsByBaseRepoID(ctx context.Context, repoID int64) error {
 }
 
 // MustHeadUserName returns the HeadRepo's username if failed return blank
-func (pr *PullRequest) MustHeadUserName() string {
-	if err := pr.LoadHeadRepo(); err != nil {
+func (pr *PullRequest) MustHeadUserName(ctx context.Context) string {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		if !repo_model.IsErrRepoNotExist(err) {
 			log.Error("LoadHeadRepo: %v", err)
 		} else {
@@ -220,8 +220,9 @@ func (pr *PullRequest) MustHeadUserName() string {
 	return pr.HeadRepo.OwnerName
 }
 
+// LoadAttributes loads pull request attributes from database
 // Note: don't try to get Issue because will end up recursive querying.
-func (pr *PullRequest) loadAttributes(ctx context.Context) (err error) {
+func (pr *PullRequest) LoadAttributes(ctx context.Context) (err error) {
 	if pr.HasMerged && pr.Merger == nil {
 		pr.Merger, err = user_model.GetUserByIDCtx(ctx, pr.MergerID)
 		if user_model.IsErrUserNotExist(err) {
@@ -235,13 +236,8 @@ func (pr *PullRequest) loadAttributes(ctx context.Context) (err error) {
 	return nil
 }
 
-// LoadAttributes loads pull request attributes from database
-func (pr *PullRequest) LoadAttributes() error {
-	return pr.loadAttributes(db.DefaultContext)
-}
-
-// LoadHeadRepoCtx loads the head repository
-func (pr *PullRequest) LoadHeadRepoCtx(ctx context.Context) (err error) {
+// LoadHeadRepo loads the head repository
+func (pr *PullRequest) LoadHeadRepo(ctx context.Context) (err error) {
 	if !pr.isHeadRepoLoaded && pr.HeadRepo == nil && pr.HeadRepoID > 0 {
 		if pr.HeadRepoID == pr.BaseRepoID {
 			if pr.BaseRepo != nil {
@@ -262,18 +258,8 @@ func (pr *PullRequest) LoadHeadRepoCtx(ctx context.Context) (err error) {
 	return nil
 }
 
-// LoadHeadRepo loads the head repository
-func (pr *PullRequest) LoadHeadRepo() error {
-	return pr.LoadHeadRepoCtx(db.DefaultContext)
-}
-
 // LoadBaseRepo loads the target repository
-func (pr *PullRequest) LoadBaseRepo() error {
-	return pr.LoadBaseRepoCtx(db.DefaultContext)
-}
-
-// LoadBaseRepoCtx loads the target repository
-func (pr *PullRequest) LoadBaseRepoCtx(ctx context.Context) (err error) {
+func (pr *PullRequest) LoadBaseRepo(ctx context.Context) (err error) {
 	if pr.BaseRepo != nil {
 		return nil
 	}
@@ -296,12 +282,7 @@ func (pr *PullRequest) LoadBaseRepoCtx(ctx context.Context) (err error) {
 }
 
 // LoadIssue loads issue information from database
-func (pr *PullRequest) LoadIssue() (err error) {
-	return pr.LoadIssueCtx(db.DefaultContext)
-}
-
-// LoadIssueCtx loads issue information from database
-func (pr *PullRequest) LoadIssueCtx(ctx context.Context) (err error) {
+func (pr *PullRequest) LoadIssue(ctx context.Context) (err error) {
 	if pr.Issue != nil {
 		return nil
 	}
@@ -392,7 +373,7 @@ func (pr *PullRequest) getReviewedByLines(writer io.Writer) error {
 			break
 		}
 
-		if err := review.loadReviewer(ctx); err != nil && !user_model.IsErrUserNotExist(err) {
+		if err := review.LoadReviewer(ctx); err != nil && !user_model.IsErrUserNotExist(err) {
 			log.Error("Unable to LoadReviewer[%d] for PR ID %d : %v", review.ReviewerID, pr.ID, err)
 			return err
 		} else if review.Reviewer == nil {
@@ -458,7 +439,7 @@ func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
 	}
 
 	pr.Issue = nil
-	if err := pr.LoadIssueCtx(ctx); err != nil {
+	if err := pr.LoadIssue(ctx); err != nil {
 		return false, err
 	}
 
@@ -541,9 +522,9 @@ func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue
 
 // GetUnmergedPullRequest returns a pull request that is open and has not been merged
 // by given head/base and repo/branch.
-func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string, flow PullRequestFlow) (*PullRequest, error) {
+func GetUnmergedPullRequest(ctx context.Context, headRepoID, baseRepoID int64, headBranch, baseBranch string, flow PullRequestFlow) (*PullRequest, error) {
 	pr := new(PullRequest)
-	has, err := db.GetEngine(db.DefaultContext).
+	has, err := db.GetEngine(ctx).
 		Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND flow = ? AND issue.is_closed=?",
 			headRepoID, headBranch, baseRepoID, baseBranch, false, flow, false).
 		Join("INNER", "issue", "issue.id=pull_request.issue_id").
@@ -588,10 +569,10 @@ func GetPullRequestByIndex(ctx context.Context, repoID, index int64) (*PullReque
 		return nil, ErrPullRequestNotExist{0, 0, 0, repoID, "", ""}
 	}
 
-	if err = pr.loadAttributes(ctx); err != nil {
+	if err = pr.LoadAttributes(ctx); err != nil {
 		return nil, err
 	}
-	if err = pr.LoadIssueCtx(ctx); err != nil {
+	if err = pr.LoadIssue(ctx); err != nil {
 		return nil, err
 	}
 
@@ -607,7 +588,7 @@ func GetPullRequestByID(ctx context.Context, id int64) (*PullRequest, error) {
 	} else if !has {
 		return nil, ErrPullRequestNotExist{id, 0, 0, 0, "", ""}
 	}
-	return pr, pr.loadAttributes(ctx)
+	return pr, pr.LoadAttributes(ctx)
 }
 
 // GetPullRequestByIssueIDWithNoAttributes returns pull request with no attributes loaded by given issue ID.
@@ -634,7 +615,7 @@ func GetPullRequestByIssueID(ctx context.Context, issueID int64) (*PullRequest,
 	} else if !has {
 		return nil, ErrPullRequestNotExist{0, issueID, 0, 0, "", ""}
 	}
-	return pr, pr.loadAttributes(ctx)
+	return pr, pr.LoadAttributes(ctx)
 }
 
 // GetAllUnmergedAgitPullRequestByPoster get all unmerged agit flow pull request
@@ -664,14 +645,15 @@ func (pr *PullRequest) UpdateCols(cols ...string) error {
 }
 
 // UpdateColsIfNotMerged updates specific fields of a pull request if it has not been merged
-func (pr *PullRequest) UpdateColsIfNotMerged(cols ...string) error {
-	_, err := db.GetEngine(db.DefaultContext).Where("id = ? AND has_merged = ?", pr.ID, false).Cols(cols...).Update(pr)
+func (pr *PullRequest) UpdateColsIfNotMerged(ctx context.Context, cols ...string) error {
+	_, err := db.GetEngine(ctx).Where("id = ? AND has_merged = ?", pr.ID, false).Cols(cols...).Update(pr)
 	return err
 }
 
 // IsWorkInProgress determine if the Pull Request is a Work In Progress by its title
+// Issue must be set before this method can be called.
 func (pr *PullRequest) IsWorkInProgress() bool {
-	if err := pr.LoadIssue(); err != nil {
+	if err := pr.LoadIssue(db.DefaultContext); err != nil {
 		log.Error("LoadIssue: %v", err)
 		return false
 	}
@@ -695,8 +677,8 @@ func (pr *PullRequest) IsFilesConflicted() bool {
 
 // GetWorkInProgressPrefix returns the prefix used to mark the pull request as a work in progress.
 // It returns an empty string when none were found
-func (pr *PullRequest) GetWorkInProgressPrefix() string {
-	if err := pr.LoadIssue(); err != nil {
+func (pr *PullRequest) GetWorkInProgressPrefix(ctx context.Context) string {
+	if err := pr.LoadIssue(ctx); err != nil {
 		log.Error("LoadIssue: %v", err)
 		return ""
 	}
@@ -739,7 +721,7 @@ func GetPullRequestsByHeadBranch(ctx context.Context, headBranch string, headRep
 
 // GetBaseBranchHTMLURL returns the HTML URL of the base branch
 func (pr *PullRequest) GetBaseBranchHTMLURL() string {
-	if err := pr.LoadBaseRepo(); err != nil {
+	if err := pr.LoadBaseRepo(db.DefaultContext); err != nil {
 		log.Error("LoadBaseRepo: %v", err)
 		return ""
 	}
@@ -755,7 +737,7 @@ func (pr *PullRequest) GetHeadBranchHTMLURL() string {
 		return ""
 	}
 
-	if err := pr.LoadHeadRepo(); err != nil {
+	if err := pr.LoadHeadRepo(db.DefaultContext); err != nil {
 		log.Error("LoadHeadRepo: %v", err)
 		return ""
 	}
diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go
index c69f18492..6110ba77f 100644
--- a/models/issues/pull_list.go
+++ b/models/issues/pull_list.go
@@ -79,7 +79,7 @@ func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *
 
 	for _, pr := range prs {
 		if pr.AllowMaintainerEdit {
-			err = pr.LoadBaseRepo()
+			err = pr.LoadBaseRepo(db.DefaultContext)
 			if err != nil {
 				continue
 			}
diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go
index fb46e3071..d88f9d4f5 100644
--- a/models/issues/pull_test.go
+++ b/models/issues/pull_test.go
@@ -17,7 +17,7 @@ import (
 func TestPullRequest_LoadAttributes(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadAttributes())
+	assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
 	assert.NotNil(t, pr.Merger)
 	assert.Equal(t, pr.MergerID, pr.Merger.ID)
 }
@@ -25,10 +25,10 @@ func TestPullRequest_LoadAttributes(t *testing.T) {
 func TestPullRequest_LoadIssue(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadIssue())
+	assert.NoError(t, pr.LoadIssue(db.DefaultContext))
 	assert.NotNil(t, pr.Issue)
 	assert.Equal(t, int64(2), pr.Issue.ID)
-	assert.NoError(t, pr.LoadIssue())
+	assert.NoError(t, pr.LoadIssue(db.DefaultContext))
 	assert.NotNil(t, pr.Issue)
 	assert.Equal(t, int64(2), pr.Issue.ID)
 }
@@ -36,10 +36,10 @@ func TestPullRequest_LoadIssue(t *testing.T) {
 func TestPullRequest_LoadBaseRepo(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadBaseRepo())
+	assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
 	assert.NotNil(t, pr.BaseRepo)
 	assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
-	assert.NoError(t, pr.LoadBaseRepo())
+	assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
 	assert.NotNil(t, pr.BaseRepo)
 	assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
 }
@@ -47,7 +47,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) {
 func TestPullRequest_LoadHeadRepo(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadHeadRepo())
+	assert.NoError(t, pr.LoadHeadRepo(db.DefaultContext))
 	assert.NotNil(t, pr.HeadRepo)
 	assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID)
 }
@@ -96,11 +96,11 @@ func TestPullRequestsOldest(t *testing.T) {
 
 func TestGetUnmergedPullRequest(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
-	pr, err := issues_model.GetUnmergedPullRequest(1, 1, "branch2", "master", issues_model.PullRequestFlowGithub)
+	pr, err := issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub)
 	assert.NoError(t, err)
 	assert.Equal(t, int64(2), pr.ID)
 
-	_, err = issues_model.GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub)
+	_, err = issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub)
 	assert.Error(t, err)
 	assert.True(t, issues_model.IsErrPullRequestNotExist(err))
 }
@@ -228,7 +228,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
-	pr.LoadIssue()
+	pr.LoadIssue(db.DefaultContext)
 
 	assert.False(t, pr.IsWorkInProgress())
 
@@ -243,16 +243,16 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
-	pr.LoadIssue()
+	pr.LoadIssue(db.DefaultContext)
 
-	assert.Empty(t, pr.GetWorkInProgressPrefix())
+	assert.Empty(t, pr.GetWorkInProgressPrefix(db.DefaultContext))
 
 	original := pr.Issue.Title
 	pr.Issue.Title = "WIP: " + original
-	assert.Equal(t, "WIP:", pr.GetWorkInProgressPrefix())
+	assert.Equal(t, "WIP:", pr.GetWorkInProgressPrefix(db.DefaultContext))
 
 	pr.Issue.Title = "[wip] " + original
-	assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix())
+	assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix(db.DefaultContext))
 }
 
 func TestDeleteOrphanedObjects(t *testing.T) {
@@ -264,11 +264,11 @@ func TestDeleteOrphanedObjects(t *testing.T) {
 	_, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
 	assert.NoError(t, err)
 
-	orphaned, err := db.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
+	orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
 	assert.NoError(t, err)
 	assert.EqualValues(t, 3, orphaned)
 
-	err = db.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
+	err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
 	assert.NoError(t, err)
 
 	countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
diff --git a/models/issues/review.go b/models/issues/review.go
index f66c70c1f..5cf7d4c3d 100644
--- a/models/issues/review.go
+++ b/models/issues/review.go
@@ -154,7 +154,8 @@ func (r *Review) loadIssue(ctx context.Context) (err error) {
 	return err
 }
 
-func (r *Review) loadReviewer(ctx context.Context) (err error) {
+// LoadReviewer loads reviewer
+func (r *Review) LoadReviewer(ctx context.Context) (err error) {
 	if r.ReviewerID == 0 || r.Reviewer != nil {
 		return
 	}
@@ -162,7 +163,8 @@ func (r *Review) loadReviewer(ctx context.Context) (err error) {
 	return err
 }
 
-func (r *Review) loadReviewerTeam(ctx context.Context) (err error) {
+// LoadReviewerTeam loads reviewer team
+func (r *Review) LoadReviewerTeam(ctx context.Context) (err error) {
 	if r.ReviewerTeamID == 0 || r.ReviewerTeam != nil {
 		return
 	}
@@ -171,16 +173,6 @@ func (r *Review) loadReviewerTeam(ctx context.Context) (err error) {
 	return err
 }
 
-// LoadReviewer loads reviewer
-func (r *Review) LoadReviewer() error {
-	return r.loadReviewer(db.DefaultContext)
-}
-
-// LoadReviewerTeam loads reviewer team
-func (r *Review) LoadReviewerTeam() error {
-	return r.loadReviewerTeam(db.DefaultContext)
-}
-
 // LoadAttributes loads all attributes except CodeComments
 func (r *Review) LoadAttributes(ctx context.Context) (err error) {
 	if err = r.loadIssue(ctx); err != nil {
@@ -189,10 +181,10 @@ func (r *Review) LoadAttributes(ctx context.Context) (err error) {
 	if err = r.LoadCodeComments(ctx); err != nil {
 		return
 	}
-	if err = r.loadReviewer(ctx); err != nil {
+	if err = r.LoadReviewer(ctx); err != nil {
 		return
 	}
-	if err = r.loadReviewerTeam(ctx); err != nil {
+	if err = r.LoadReviewerTeam(ctx); err != nil {
 		return
 	}
 	return err
diff --git a/models/issues/review_test.go b/models/issues/review_test.go
index 46d1cc777..39ad14c65 100644
--- a/models/issues/review_test.go
+++ b/models/issues/review_test.go
@@ -135,7 +135,7 @@ func TestGetReviewersByIssueID(t *testing.T) {
 
 	allReviews, err := issues_model.GetReviewersByIssueID(issue.ID)
 	for _, reviewer := range allReviews {
-		assert.NoError(t, reviewer.LoadReviewer())
+		assert.NoError(t, reviewer.LoadReviewer(db.DefaultContext))
 	}
 	assert.NoError(t, err)
 	if assert.Len(t, allReviews, 3) {
diff --git a/models/org_team_test.go b/models/org_team_test.go
index a600d07c0..3b1fabf1c 100644
--- a/models/org_team_test.go
+++ b/models/org_team_test.go
@@ -143,7 +143,7 @@ func TestDeleteTeam(t *testing.T) {
 	// check that team members don't have "leftover" access to repos
 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
-	accessMode, err := access_model.AccessLevel(user, repo)
+	accessMode, err := access_model.AccessLevel(db.DefaultContext, user, repo)
 	assert.NoError(t, err)
 	assert.True(t, accessMode < perm.AccessModeWrite)
 }
diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go
index 7f58be4f3..dc707b971 100644
--- a/models/perm/access/access_test.go
+++ b/models/perm/access/access_test.go
@@ -36,34 +36,34 @@ func TestAccessLevel(t *testing.T) {
 	// org. owned private repo
 	repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24})
 
-	level, err := access_model.AccessLevel(user2, repo1)
+	level, err := access_model.AccessLevel(db.DefaultContext, user2, repo1)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeOwner, level)
 
-	level, err = access_model.AccessLevel(user2, repo3)
+	level, err = access_model.AccessLevel(db.DefaultContext, user2, repo3)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeOwner, level)
 
-	level, err = access_model.AccessLevel(user5, repo1)
+	level, err = access_model.AccessLevel(db.DefaultContext, user5, repo1)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeRead, level)
 
-	level, err = access_model.AccessLevel(user5, repo3)
+	level, err = access_model.AccessLevel(db.DefaultContext, user5, repo3)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeNone, level)
 
 	// restricted user has no access to a public repo
-	level, err = access_model.AccessLevel(user29, repo1)
+	level, err = access_model.AccessLevel(db.DefaultContext, user29, repo1)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeNone, level)
 
 	// ... unless he's a collaborator
-	level, err = access_model.AccessLevel(user29, repo4)
+	level, err = access_model.AccessLevel(db.DefaultContext, user29, repo4)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeWrite, level)
 
 	// ... or a team member
-	level, err = access_model.AccessLevel(user29, repo24)
+	level, err = access_model.AccessLevel(db.DefaultContext, user29, repo24)
 	assert.NoError(t, err)
 	assert.Equal(t, perm_model.AccessModeRead, level)
 }
diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go
index 93e3bdd6d..3b709a3e8 100644
--- a/models/perm/access/repo_permission.go
+++ b/models/perm/access/repo_permission.go
@@ -326,17 +326,13 @@ func IsUserRepoAdmin(ctx context.Context, repo *repo_model.Repository, user *use
 
 // AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
 // user does not have access.
-func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) { //nolint
-	return AccessLevelUnit(user, repo, unit.TypeCode)
+func AccessLevel(ctx context.Context, user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) { //nolint
+	return AccessLevelUnit(ctx, user, repo, unit.TypeCode)
 }
 
 // AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the
 // user does not have access.
-func AccessLevelUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { //nolint
-	return accessLevelUnit(db.DefaultContext, user, repo, unitType)
-}
-
-func accessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) {
+func AccessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { //nolint
 	perm, err := GetUserRepoPermission(ctx, repo, user)
 	if err != nil {
 		return perm_model.AccessModeNone, err
@@ -346,7 +342,7 @@ func accessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_mode
 
 // HasAccessUnit returns true if user has testMode to the unit of the repository
 func HasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) {
-	mode, err := accessLevelUnit(ctx, user, repo, unitType)
+	mode, err := AccessLevelUnit(ctx, user, repo, unitType)
 	return testMode <= mode, err
 }
 
diff --git a/models/repo/attachment.go b/models/repo/attachment.go
index df7528df0..428f370a0 100644
--- a/models/repo/attachment.go
+++ b/models/repo/attachment.go
@@ -226,20 +226,20 @@ func UpdateAttachment(ctx context.Context, atta *Attachment) error {
 }
 
 // DeleteAttachmentsByRelease deletes all attachments associated with the given release.
-func DeleteAttachmentsByRelease(releaseID int64) error {
-	_, err := db.GetEngine(db.DefaultContext).Where("release_id = ?", releaseID).Delete(&Attachment{})
+func DeleteAttachmentsByRelease(ctx context.Context, releaseID int64) error {
+	_, err := db.GetEngine(ctx).Where("release_id = ?", releaseID).Delete(&Attachment{})
 	return err
 }
 
 // CountOrphanedAttachments returns the number of bad attachments
-func CountOrphanedAttachments() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))").
+func CountOrphanedAttachments(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))").
 		Count(new(Attachment))
 }
 
 // DeleteOrphanedAttachments delete all bad attachments
-func DeleteOrphanedAttachments() error {
-	_, err := db.GetEngine(db.DefaultContext).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))").
+func DeleteOrphanedAttachments(ctx context.Context) error {
+	_, err := db.GetEngine(ctx).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))").
 		Delete(new(Attachment))
 	return err
 }
diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go
index 38d6e7201..fa876ee56 100644
--- a/models/repo/pushmirror.go
+++ b/models/repo/pushmirror.go
@@ -120,9 +120,9 @@ func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.Li
 }
 
 // GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
-func GetPushMirrorsSyncedOnCommit(repoID int64) ([]*PushMirror, error) {
+func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) {
 	mirrors := make([]*PushMirror, 0, 10)
-	return mirrors, db.GetEngine(db.DefaultContext).
+	return mirrors, db.GetEngine(ctx).
 		Where("repo_id=? AND sync_on_commit=?", repoID, true).
 		Find(&mirrors)
 }
diff --git a/models/repo/release.go b/models/repo/release.go
index 14428f15f..a92e4bb6e 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -90,7 +90,8 @@ func init() {
 	db.RegisterModel(new(Release))
 }
 
-func (r *Release) loadAttributes(ctx context.Context) error {
+// LoadAttributes load repo and publisher attributes for a release
+func (r *Release) LoadAttributes(ctx context.Context) error {
 	var err error
 	if r.Repo == nil {
 		r.Repo, err = GetRepositoryByIDCtx(ctx, r.RepoID)
@@ -111,11 +112,6 @@ func (r *Release) loadAttributes(ctx context.Context) error {
 	return GetReleaseAttachments(ctx, r)
 }
 
-// LoadAttributes load repo and publisher attributes for a release
-func (r *Release) LoadAttributes() error {
-	return r.loadAttributes(db.DefaultContext)
-}
-
 // APIURL the api url for a release. release must have attributes loaded
 func (r *Release) APIURL() string {
 	return r.Repo.APIURL() + "/releases/" + strconv.FormatInt(r.ID, 10)
@@ -241,8 +237,8 @@ func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
 }
 
 // GetReleasesByRepoID returns a list of releases of repository.
-func GetReleasesByRepoID(repoID int64, opts FindReleasesOptions) ([]*Release, error) {
-	sess := db.GetEngine(db.DefaultContext).
+func GetReleasesByRepoID(ctx context.Context, repoID int64, opts FindReleasesOptions) ([]*Release, error) {
+	sess := db.GetEngine(ctx).
 		Desc("created_unix", "id").
 		Where(opts.toConds(repoID))
 
@@ -381,8 +377,8 @@ func SortReleases(rels []*Release) {
 }
 
 // DeleteReleaseByID deletes a release from database by given ID.
-func DeleteReleaseByID(id int64) error {
-	_, err := db.GetEngine(db.DefaultContext).ID(id).Delete(new(Release))
+func DeleteReleaseByID(ctx context.Context, id int64) error {
+	_, err := db.GetEngine(ctx).ID(id).Delete(new(Release))
 	return err
 }
 
diff --git a/models/repo/repo.go b/models/repo/repo.go
index 77e0367a5..a3dac8383 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -236,14 +236,6 @@ func (repo *Repository) AfterLoad() {
 	repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
 }
 
-// MustOwner always returns a valid *user_model.User object to avoid
-// conceptually impossible error handling.
-// It creates a fake object that contains error details
-// when error occurs.
-func (repo *Repository) MustOwner() *user_model.User {
-	return repo.mustOwner(db.DefaultContext)
-}
-
 // LoadAttributes loads attributes of the repository.
 func (repo *Repository) LoadAttributes(ctx context.Context) error {
 	// Load owner
@@ -403,7 +395,11 @@ func (repo *Repository) GetOwner(ctx context.Context) (err error) {
 	return err
 }
 
-func (repo *Repository) mustOwner(ctx context.Context) *user_model.User {
+// MustOwner always returns a valid *user_model.User object to avoid
+// conceptually impossible error handling.
+// It creates a fake object that contains error details
+// when error occurs.
+func (repo *Repository) MustOwner(ctx context.Context) *user_model.User {
 	if err := repo.GetOwner(ctx); err != nil {
 		return &user_model.User{
 			Name:     "error",
@@ -438,7 +434,7 @@ func (repo *Repository) ComposeMetas() map[string]string {
 			}
 		}
 
-		repo.MustOwner()
+		repo.MustOwner(db.DefaultContext)
 		if repo.Owner.IsOrganization() {
 			teams := make([]string, 0, 5)
 			_ = db.GetEngine(db.DefaultContext).Table("team_repo").
@@ -792,13 +788,13 @@ func UpdateRepoIssueNumbers(ctx context.Context, repoID int64, isPull, isClosed
 }
 
 // CountNullArchivedRepository counts the number of repositories with is_archived is null
-func CountNullArchivedRepository() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(Repository))
+func CountNullArchivedRepository(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where(builder.IsNull{"is_archived"}).Count(new(Repository))
 }
 
 // FixNullArchivedRepository sets is_archived to false where it is null
-func FixNullArchivedRepository() (int64, error) {
-	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&Repository{
+func FixNullArchivedRepository(ctx context.Context) (int64, error) {
+	return db.GetEngine(ctx).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&Repository{
 		IsArchived: false,
 	})
 }
diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go
index 191970d27..abfa73abb 100644
--- a/models/repo/repo_list.go
+++ b/models/repo/repo_list.go
@@ -518,14 +518,13 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
 
 // SearchRepository returns repositories based on search options,
 // it returns results in given range and number of total results.
-func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
+func SearchRepository(ctx context.Context, opts *SearchRepoOptions) (RepositoryList, int64, error) {
 	cond := SearchRepositoryCondition(opts)
-	return SearchRepositoryByCondition(opts, cond, true)
+	return SearchRepositoryByCondition(ctx, opts, cond, true)
 }
 
 // SearchRepositoryByCondition search repositories by condition
-func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loadAttributes bool) (RepositoryList, int64, error) {
-	ctx := db.DefaultContext
+func SearchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, cond builder.Cond, loadAttributes bool) (RepositoryList, int64, error) {
 	sess, count, err := searchRepositoryByCondition(ctx, opts, cond)
 	if err != nil {
 		return nil, 0, err
@@ -652,9 +651,9 @@ func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) bu
 
 // SearchRepositoryByName takes keyword and part of repository name to search,
 // it returns results in given range and number of total results.
-func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, error) {
+func SearchRepositoryByName(ctx context.Context, opts *SearchRepoOptions) (RepositoryList, int64, error) {
 	opts.IncludeDescription = false
-	return SearchRepository(opts)
+	return SearchRepository(ctx, opts)
 }
 
 // SearchRepositoryIDs takes keyword and part of repository name to search,
diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go
index f9c84a0f3..926ed07e9 100644
--- a/models/repo/repo_list_test.go
+++ b/models/repo/repo_list_test.go
@@ -20,7 +20,7 @@ func TestSearchRepository(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
 	// test search public repository on explore page
-	repos, count, err := repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+	repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -35,7 +35,7 @@ func TestSearchRepository(t *testing.T) {
 	}
 	assert.Equal(t, int64(1), count)
 
-	repos, count, err = repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -49,7 +49,7 @@ func TestSearchRepository(t *testing.T) {
 	assert.Len(t, repos, 2)
 
 	// test search private repository on explore page
-	repos, count, err = repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -65,7 +65,7 @@ func TestSearchRepository(t *testing.T) {
 	}
 	assert.Equal(t, int64(1), count)
 
-	repos, count, err = repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -80,14 +80,14 @@ func TestSearchRepository(t *testing.T) {
 	assert.Len(t, repos, 3)
 
 	// Test non existing owner
-	repos, count, err = repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID})
+	repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID})
 
 	assert.NoError(t, err)
 	assert.Empty(t, repos)
 	assert.Equal(t, int64(0), count)
 
 	// Test search within description
-	repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -104,7 +104,7 @@ func TestSearchRepository(t *testing.T) {
 	assert.Equal(t, int64(1), count)
 
 	// Test NOT search within description
-	repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     1,
 			PageSize: 10,
@@ -277,7 +277,7 @@ func TestSearchRepository(t *testing.T) {
 
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			repos, count, err := repo_model.SearchRepositoryByName(testCase.opts)
+			repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts)
 
 			assert.NoError(t, err)
 			assert.Equal(t, int64(testCase.count), count)
@@ -377,7 +377,7 @@ func TestSearchRepositoryByTopicName(t *testing.T) {
 
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			_, count, err := repo_model.SearchRepositoryByName(testCase.opts)
+			_, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts)
 			assert.NoError(t, err)
 			assert.Equal(t, int64(testCase.count), count)
 		})
diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go
index e7125f70f..9ca367f55 100644
--- a/models/repo/user_repo.go
+++ b/models/repo/user_repo.go
@@ -17,8 +17,9 @@ import (
 )
 
 // GetStarredRepos returns the repos starred by a particular user
-func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]*Repository, error) {
-	sess := db.GetEngine(db.DefaultContext).Where("star.uid=?", userID).
+func GetStarredRepos(ctx context.Context, userID int64, private bool, listOptions db.ListOptions) ([]*Repository, error) {
+	sess := db.GetEngine(ctx).
+		Where("star.uid=?", userID).
 		Join("LEFT", "star", "`repository`.id=`star`.repo_id")
 	if !private {
 		sess = sess.And("is_private=?", false)
@@ -36,8 +37,9 @@ func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]
 }
 
 // GetWatchedRepos returns the repos watched by a particular user
-func GetWatchedRepos(userID int64, private bool, listOptions db.ListOptions) ([]*Repository, int64, error) {
-	sess := db.GetEngine(db.DefaultContext).Where("watch.user_id=?", userID).
+func GetWatchedRepos(ctx context.Context, userID int64, private bool, listOptions db.ListOptions) ([]*Repository, int64, error) {
+	sess := db.GetEngine(ctx).
+		Where("watch.user_id=?", userID).
 		And("`watch`.mode<>?", WatchModeDont).
 		Join("LEFT", "watch", "`repository`.id=`watch`.repo_id")
 	if !private {
diff --git a/models/user/user.go b/models/user/user.go
index c36fc21c7..1a71acb0b 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -1042,14 +1042,15 @@ func GetUserEmailsByNames(ctx context.Context, names []string) []string {
 }
 
 // GetMaileableUsersByIDs gets users from ids, but only if they can receive mails
-func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) {
+func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) {
 	if len(ids) == 0 {
 		return nil, nil
 	}
 	ous := make([]*User, 0, len(ids))
 
 	if isMention {
-		return ous, db.GetEngine(db.DefaultContext).In("id", ids).
+		return ous, db.GetEngine(ctx).
+			In("id", ids).
 			Where("`type` = ?", UserTypeIndividual).
 			And("`prohibit_login` = ?", false).
 			And("`is_active` = ?", true).
@@ -1057,7 +1058,8 @@ func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) {
 			Find(&ous)
 	}
 
-	return ous, db.GetEngine(db.DefaultContext).In("id", ids).
+	return ous, db.GetEngine(ctx).
+		In("id", ids).
 		Where("`type` = ?", UserTypeIndividual).
 		And("`prohibit_login` = ?", false).
 		And("`is_active` = ?", true).
@@ -1090,10 +1092,10 @@ func GetUserNameByID(ctx context.Context, id int64) (string, error) {
 }
 
 // GetUserIDsByNames returns a slice of ids corresponds to names.
-func GetUserIDsByNames(names []string, ignoreNonExistent bool) ([]int64, error) {
+func GetUserIDsByNames(ctx context.Context, names []string, ignoreNonExistent bool) ([]int64, error) {
 	ids := make([]int64, 0, len(names))
 	for _, name := range names {
-		u, err := GetUserByName(db.DefaultContext, name)
+		u, err := GetUserByName(ctx, name)
 		if err != nil {
 			if ignoreNonExistent {
 				continue
diff --git a/models/user/user_test.go b/models/user/user_test.go
index 5f2ac0a60..1cdfb5978 100644
--- a/models/user/user_test.go
+++ b/models/user/user_test.go
@@ -257,12 +257,12 @@ func TestGetUserIDsByNames(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
 	// ignore non existing
-	IDs, err := user_model.GetUserIDsByNames([]string{"user1", "user2", "none_existing_user"}, true)
+	IDs, err := user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "user2", "none_existing_user"}, true)
 	assert.NoError(t, err)
 	assert.Equal(t, []int64{1, 2}, IDs)
 
 	// ignore non existing
-	IDs, err = user_model.GetUserIDsByNames([]string{"user1", "do_not_exist"}, false)
+	IDs, err = user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "do_not_exist"}, false)
 	assert.Error(t, err)
 	assert.Equal(t, []int64(nil), IDs)
 }
@@ -270,14 +270,14 @@ func TestGetUserIDsByNames(t *testing.T) {
 func TestGetMaileableUsersByIDs(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
-	results, err := user_model.GetMaileableUsersByIDs([]int64{1, 4}, false)
+	results, err := user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, false)
 	assert.NoError(t, err)
 	assert.Len(t, results, 1)
 	if len(results) > 1 {
 		assert.Equal(t, results[0].ID, 1)
 	}
 
-	results, err = user_model.GetMaileableUsersByIDs([]int64{1, 4}, true)
+	results, err = user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, true)
 	assert.NoError(t, err)
 	assert.Len(t, results, 2)
 	if len(results) > 2 {
diff --git a/modules/convert/issue.go b/modules/convert/issue.go
index 5364367a8..7c11b2a89 100644
--- a/modules/convert/issue.go
+++ b/modules/convert/issue.go
@@ -5,6 +5,7 @@
 package convert
 
 import (
+	"context"
 	"fmt"
 	"net/url"
 	"strings"
@@ -22,17 +23,17 @@ import (
 // it assumes some fields assigned with values:
 // Required - Poster, Labels,
 // Optional - Milestone, Assignee, PullRequest
-func ToAPIIssue(issue *issues_model.Issue) *api.Issue {
-	if err := issue.LoadLabels(db.DefaultContext); err != nil {
+func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
+	if err := issue.LoadLabels(ctx); err != nil {
 		return &api.Issue{}
 	}
-	if err := issue.LoadPoster(); err != nil {
+	if err := issue.LoadPoster(ctx); err != nil {
 		return &api.Issue{}
 	}
-	if err := issue.LoadRepo(db.DefaultContext); err != nil {
+	if err := issue.LoadRepo(ctx); err != nil {
 		return &api.Issue{}
 	}
-	if err := issue.Repo.GetOwner(db.DefaultContext); err != nil {
+	if err := issue.Repo.GetOwner(ctx); err != nil {
 		return &api.Issue{}
 	}
 
@@ -64,14 +65,14 @@ func ToAPIIssue(issue *issues_model.Issue) *api.Issue {
 		apiIssue.Closed = issue.ClosedUnix.AsTimePtr()
 	}
 
-	if err := issue.LoadMilestone(); err != nil {
+	if err := issue.LoadMilestone(ctx); err != nil {
 		return &api.Issue{}
 	}
 	if issue.Milestone != nil {
 		apiIssue.Milestone = ToAPIMilestone(issue.Milestone)
 	}
 
-	if err := issue.LoadAssignees(db.DefaultContext); err != nil {
+	if err := issue.LoadAssignees(ctx); err != nil {
 		return &api.Issue{}
 	}
 	if len(issue.Assignees) > 0 {
@@ -81,7 +82,7 @@ func ToAPIIssue(issue *issues_model.Issue) *api.Issue {
 		apiIssue.Assignee = ToUser(issue.Assignees[0], nil) // For compatibility, we're keeping the first assignee as `apiIssue.Assignee`
 	}
 	if issue.IsPull {
-		if err := issue.LoadPullRequest(); err != nil {
+		if err := issue.LoadPullRequest(ctx); err != nil {
 			return &api.Issue{}
 		}
 		apiIssue.PullRequest = &api.PullRequestMeta{
@@ -99,16 +100,16 @@ func ToAPIIssue(issue *issues_model.Issue) *api.Issue {
 }
 
 // ToAPIIssueList converts an IssueList to API format
-func ToAPIIssueList(il issues_model.IssueList) []*api.Issue {
+func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
 	result := make([]*api.Issue, len(il))
 	for i := range il {
-		result[i] = ToAPIIssue(il[i])
+		result[i] = ToAPIIssue(ctx, il[i])
 	}
 	return result
 }
 
 // ToTrackedTime converts TrackedTime to API format
-func ToTrackedTime(t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
+func ToTrackedTime(ctx context.Context, t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
 	apiT = &api.TrackedTime{
 		ID:       t.ID,
 		IssueID:  t.IssueID,
@@ -118,7 +119,7 @@ func ToTrackedTime(t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
 		Created:  t.Created,
 	}
 	if t.Issue != nil {
-		apiT.Issue = ToAPIIssue(t.Issue)
+		apiT.Issue = ToAPIIssue(ctx, t.Issue)
 	}
 	if t.User != nil {
 		apiT.UserName = t.User.Name
@@ -169,10 +170,10 @@ func ToStopWatches(sws []*issues_model.Stopwatch) (api.StopWatches, error) {
 }
 
 // ToTrackedTimeList converts TrackedTimeList to API format
-func ToTrackedTimeList(tl issues_model.TrackedTimeList) api.TrackedTimeList {
+func ToTrackedTimeList(ctx context.Context, tl issues_model.TrackedTimeList) api.TrackedTimeList {
 	result := make([]*api.TrackedTime, 0, len(tl))
 	for _, t := range tl {
-		result = append(result, ToTrackedTime(t))
+		result = append(result, ToTrackedTime(ctx, t))
 	}
 	return result
 }
diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go
index 73ad345fa..c33cf5c11 100644
--- a/modules/convert/issue_comment.go
+++ b/modules/convert/issue_comment.go
@@ -5,7 +5,8 @@
 package convert
 
 import (
-	"code.gitea.io/gitea/models/db"
+	"context"
+
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
@@ -28,8 +29,8 @@ func ToComment(c *issues_model.Comment) *api.Comment {
 }
 
 // ToTimelineComment converts a issues_model.Comment to the api.TimelineComment format
-func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.TimelineComment {
-	err := c.LoadMilestone()
+func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_model.User) *api.TimelineComment {
+	err := c.LoadMilestone(ctx)
 	if err != nil {
 		log.Error("LoadMilestone: %v", err)
 		return nil
@@ -107,25 +108,25 @@ func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.Time
 			return nil
 		}
 
-		comment.TrackedTime = ToTrackedTime(c.Time)
+		comment.TrackedTime = ToTrackedTime(ctx, c.Time)
 	}
 
 	if c.RefIssueID != 0 {
-		issue, err := issues_model.GetIssueByID(db.DefaultContext, c.RefIssueID)
+		issue, err := issues_model.GetIssueByID(ctx, c.RefIssueID)
 		if err != nil {
 			log.Error("GetIssueByID(%d): %v", c.RefIssueID, err)
 			return nil
 		}
-		comment.RefIssue = ToAPIIssue(issue)
+		comment.RefIssue = ToAPIIssue(ctx, issue)
 	}
 
 	if c.RefCommentID != 0 {
-		com, err := issues_model.GetCommentByID(db.DefaultContext, c.RefCommentID)
+		com, err := issues_model.GetCommentByID(ctx, c.RefCommentID)
 		if err != nil {
 			log.Error("GetCommentByID(%d): %v", c.RefCommentID, err)
 			return nil
 		}
-		err = com.LoadPoster()
+		err = com.LoadPoster(ctx)
 		if err != nil {
 			log.Error("LoadPoster: %v", err)
 			return nil
@@ -138,17 +139,17 @@ func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.Time
 		var repo *repo_model.Repository
 		if c.Label.BelongsToOrg() {
 			var err error
-			org, err = user_model.GetUserByID(c.Label.OrgID)
+			org, err = user_model.GetUserByIDCtx(ctx, c.Label.OrgID)
 			if err != nil {
-				log.Error("GetUserByID(%d): %v", c.Label.OrgID, err)
+				log.Error("GetUserByIDCtx(%d): %v", c.Label.OrgID, err)
 				return nil
 			}
 		}
 		if c.Label.BelongsToRepo() {
 			var err error
-			repo, err = repo_model.GetRepositoryByID(c.Label.RepoID)
+			repo, err = repo_model.GetRepositoryByIDCtx(ctx, c.Label.RepoID)
 			if err != nil {
-				log.Error("GetRepositoryByID(%d): %v", c.Label.RepoID, err)
+				log.Error("GetRepositoryByIDCtx(%d): %v", c.Label.RepoID, err)
 				return nil
 			}
 		}
@@ -167,7 +168,7 @@ func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.Time
 	}
 
 	if c.DependentIssue != nil {
-		comment.DependentIssue = ToAPIIssue(c.DependentIssue)
+		comment.DependentIssue = ToAPIIssue(ctx, c.DependentIssue)
 	}
 
 	return comment
diff --git a/modules/convert/pull.go b/modules/convert/pull.go
index 9c31f9bd2..ca9a4c39c 100644
--- a/modules/convert/pull.go
+++ b/modules/convert/pull.go
@@ -33,13 +33,13 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
 		return nil
 	}
 
-	apiIssue := ToAPIIssue(pr.Issue)
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	apiIssue := ToAPIIssue(ctx, pr.Issue)
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("GetRepositoryById[%d]: %v", pr.ID, err)
 		return nil
 	}
 
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		log.Error("GetRepositoryById[%d]: %v", pr.ID, err)
 		return nil
 	}
diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go
index a6ccbaca5..a0a672d3a 100644
--- a/modules/convert/pull_test.go
+++ b/modules/convert/pull_test.go
@@ -7,6 +7,7 @@ package convert
 import (
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	"code.gitea.io/gitea/models/perm"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -22,8 +23,8 @@ func TestPullRequest_APIFormat(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadAttributes())
-	assert.NoError(t, pr.LoadIssue())
+	assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
+	assert.NoError(t, pr.LoadIssue(db.DefaultContext))
 	apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil)
 	assert.NotNil(t, apiPullRequest)
 	assert.EqualValues(t, &structs.PRBranchInfo{
@@ -36,8 +37,8 @@ func TestPullRequest_APIFormat(t *testing.T) {
 
 	// withOut HeadRepo
 	pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
-	assert.NoError(t, pr.LoadIssue())
-	assert.NoError(t, pr.LoadAttributes())
+	assert.NoError(t, pr.LoadIssue(db.DefaultContext))
+	assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
 	// simulate fork deletion
 	pr.HeadRepo = nil
 	pr.HeadRepoID = 100000
diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go
index 89d974a35..602b2e523 100644
--- a/modules/doctor/dbconsistency.go
+++ b/modules/doctor/dbconsistency.go
@@ -18,13 +18,13 @@ import (
 
 type consistencyCheck struct {
 	Name         string
-	Counter      func() (int64, error)
-	Fixer        func() (int64, error)
+	Counter      func(context.Context) (int64, error)
+	Fixer        func(context.Context) (int64, error)
 	FixedMessage string
 }
 
 func (c *consistencyCheck) Run(ctx context.Context, logger log.Logger, autofix bool) error {
-	count, err := c.Counter()
+	count, err := c.Counter(ctx)
 	if err != nil {
 		logger.Critical("Error: %v whilst counting %s", err, c.Name)
 		return err
@@ -32,7 +32,7 @@ func (c *consistencyCheck) Run(ctx context.Context, logger log.Logger, autofix b
 	if count > 0 {
 		if autofix {
 			var fixed int64
-			if fixed, err = c.Fixer(); err != nil {
+			if fixed, err = c.Fixer(ctx); err != nil {
 				logger.Critical("Error: %v whilst fixing %s", err, c.Name)
 				return err
 			}
@@ -54,9 +54,9 @@ func (c *consistencyCheck) Run(ctx context.Context, logger log.Logger, autofix b
 	return nil
 }
 
-func asFixer(fn func() error) func() (int64, error) {
-	return func() (int64, error) {
-		err := fn()
+func asFixer(fn func(ctx context.Context) error) func(ctx context.Context) (int64, error) {
+	return func(ctx context.Context) (int64, error) {
+		err := fn(ctx)
 		return -1, err
 	}
 }
@@ -64,11 +64,11 @@ func asFixer(fn func() error) func() (int64, error) {
 func genericOrphanCheck(name, subject, refobject, joincond string) consistencyCheck {
 	return consistencyCheck{
 		Name: name,
-		Counter: func() (int64, error) {
-			return db.CountOrphanedObjects(subject, refobject, joincond)
+		Counter: func(ctx context.Context) (int64, error) {
+			return db.CountOrphanedObjects(ctx, subject, refobject, joincond)
 		},
-		Fixer: func() (int64, error) {
-			err := db.DeleteOrphanedObjects(subject, refobject, joincond)
+		Fixer: func(ctx context.Context) (int64, error) {
+			err := db.DeleteOrphanedObjects(ctx, subject, refobject, joincond)
 			return -1, err
 		},
 	}
diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go
index da6a200ae..5b0279d1a 100644
--- a/modules/indexer/issues/indexer.go
+++ b/modules/indexer/issues/indexer.go
@@ -291,7 +291,7 @@ func populateIssueIndexer(ctx context.Context) {
 			return
 		default:
 		}
-		repos, _, err := repo_model.SearchRepositoryByName(&repo_model.SearchRepoOptions{
+		repos, _, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
 			ListOptions: db.ListOptions{Page: page, PageSize: repo_model.RepositoryListDefaultPageSize},
 			OrderBy:     db.SearchOrderByID,
 			Private:     true,
@@ -313,14 +313,14 @@ func populateIssueIndexer(ctx context.Context) {
 				return
 			default:
 			}
-			UpdateRepoIndexer(repo)
+			UpdateRepoIndexer(ctx, repo)
 		}
 	}
 }
 
 // UpdateRepoIndexer add/update all issues of the repositories
-func UpdateRepoIndexer(repo *repo_model.Repository) {
-	is, err := issues_model.Issues(&issues_model.IssuesOptions{
+func UpdateRepoIndexer(ctx context.Context, repo *repo_model.Repository) {
+	is, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
 		RepoID:   repo.ID,
 		IsClosed: util.OptionalBoolNone,
 		IsPull:   util.OptionalBoolNone,
@@ -329,8 +329,8 @@ func UpdateRepoIndexer(repo *repo_model.Repository) {
 		log.Error("Issues: %v", err)
 		return
 	}
-	if err = issues_model.IssueList(is).LoadDiscussComments(); err != nil {
-		log.Error("LoadComments: %v", err)
+	if err = issues_model.IssueList(is).LoadDiscussComments(ctx); err != nil {
+		log.Error("LoadDiscussComments: %v", err)
 		return
 	}
 	for _, issue := range is {
@@ -360,11 +360,11 @@ func UpdateIssueIndexer(issue *issues_model.Issue) {
 }
 
 // DeleteRepoIssueIndexer deletes repo's all issues indexes
-func DeleteRepoIssueIndexer(repo *repo_model.Repository) {
+func DeleteRepoIssueIndexer(ctx context.Context, repo *repo_model.Repository) {
 	var ids []int64
-	ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, repo.ID)
+	ids, err := issues_model.GetIssueIDsByRepoID(ctx, repo.ID)
 	if err != nil {
-		log.Error("getIssueIDsByRepoID failed: %v", err)
+		log.Error("GetIssueIDsByRepoID failed: %v", err)
 		return
 	}
 
diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go
index 44d115f3d..d02940566 100644
--- a/modules/notification/action/action.go
+++ b/modules/notification/action/action.go
@@ -5,20 +5,18 @@
 package action
 
 import (
+	"context"
 	"fmt"
 	"path"
 	"strings"
 
 	activities_model "code.gitea.io/gitea/models/activities"
-	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
-	"code.gitea.io/gitea/modules/graceful"
 	"code.gitea.io/gitea/modules/json"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/notification/base"
-	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/repository"
 	"code.gitea.io/gitea/modules/util"
 )
@@ -34,18 +32,18 @@ func NewNotifier() base.Notifier {
 	return &actionNotifier{}
 }
 
-func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
-	if err := issue.LoadPoster(); err != nil {
+func (a *actionNotifier) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
+	if err := issue.LoadPoster(ctx); err != nil {
 		log.Error("issue.LoadPoster: %v", err)
 		return
 	}
-	if err := issue.LoadRepo(db.DefaultContext); err != nil {
+	if err := issue.LoadRepo(ctx); err != nil {
 		log.Error("issue.LoadRepo: %v", err)
 		return
 	}
 	repo := issue.Repo
 
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: issue.Poster.ID,
 		ActUser:   issue.Poster,
 		OpType:    activities_model.ActionCreateIssue,
@@ -59,7 +57,7 @@ func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*u
 }
 
 // NotifyIssueChangeStatus notifies close or reopen issue to notifiers
-func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
+func (a *actionNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
 	// Compose comment action, could be plain comment, close or reopen issue/pull request.
 	// This object will be used to notify watchers in the end of function.
 	act := &activities_model.Action{
@@ -86,13 +84,13 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *i
 	}
 
 	// Notify watchers for whatever action comes in, ignore if no action type.
-	if err := activities_model.NotifyWatchers(act); err != nil {
+	if err := activities_model.NotifyWatchers(ctx, act); err != nil {
 		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
 // NotifyCreateIssueComment notifies comment on an issue to notifiers
-func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (a *actionNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
 	act := &activities_model.Action{
@@ -122,26 +120,26 @@ func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *r
 	}
 
 	// Notify watchers for whatever action comes in, ignore if no action type.
-	if err := activities_model.NotifyWatchers(act); err != nil {
+	if err := activities_model.NotifyWatchers(ctx, act); err != nil {
 		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) {
-	if err := pull.LoadIssue(); err != nil {
+func (a *actionNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues_model.PullRequest, mentions []*user_model.User) {
+	if err := pull.LoadIssue(ctx); err != nil {
 		log.Error("pull.LoadIssue: %v", err)
 		return
 	}
-	if err := pull.Issue.LoadRepo(db.DefaultContext); err != nil {
+	if err := pull.Issue.LoadRepo(ctx); err != nil {
 		log.Error("pull.Issue.LoadRepo: %v", err)
 		return
 	}
-	if err := pull.Issue.LoadPoster(); err != nil {
+	if err := pull.Issue.LoadPoster(ctx); err != nil {
 		log.Error("pull.Issue.LoadPoster: %v", err)
 		return
 	}
 
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: pull.Issue.Poster.ID,
 		ActUser:   pull.Issue.Poster,
 		OpType:    activities_model.ActionCreatePullRequest,
@@ -154,8 +152,8 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, me
 	}
 }
 
-func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifyRenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldRepoName string) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionRenameRepo,
@@ -168,8 +166,8 @@ func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *rep
 	}
 }
 
-func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifyTransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionTransferRepo,
@@ -182,8 +180,8 @@ func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *r
 	}
 }
 
-func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionCreateRepo,
@@ -195,8 +193,8 @@ func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *
 	}
 }
 
-func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifyForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionCreateRepo,
@@ -208,11 +206,8 @@ func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, re
 	}
 }
 
-func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("actionNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
-	if err := review.LoadReviewer(); err != nil {
+func (a *actionNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
+	if err := review.LoadReviewer(ctx); err != nil {
 		log.Error("LoadReviewer '%d/%d': %v", review.ID, review.ReviewerID, err)
 		return
 	}
@@ -269,8 +264,8 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r
 	}
 }
 
-func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (*actionNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionMergePullRequest,
@@ -283,8 +278,8 @@ func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer
 	}
 }
 
-func (*actionNotifier) NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (*actionNotifier) NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionAutoMergePullRequest,
@@ -297,12 +292,12 @@ func (*actionNotifier) NotifyAutoMergePullRequest(pr *issues_model.PullRequest,
 	}
 }
 
-func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
+func (*actionNotifier) NotifyPullRevieweDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
 	reviewerName := review.Reviewer.Name
 	if len(review.OriginalAuthor) > 0 {
 		reviewerName = review.OriginalAuthor
 	}
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    activities_model.ActionPullReviewDismissed,
@@ -317,7 +312,7 @@ func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *i
 	}
 }
 
-func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (a *actionNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	data, err := json.Marshal(commits)
 	if err != nil {
 		log.Error("Marshal: %v", err)
@@ -336,7 +331,7 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m
 		opType = activities_model.ActionDeleteBranch
 	}
 
-	if err = activities_model.NotifyWatchers(&activities_model.Action{
+	if err = activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: pusher.ID,
 		ActUser:   pusher,
 		OpType:    opType,
@@ -346,17 +341,17 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m
 		RefName:   opts.RefFullName,
 		IsPrivate: repo.IsPrivate,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func (a *actionNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 	opType := activities_model.ActionCommitRepo
 	if refType == "tag" {
 		// has sent same action in `NotifyPushCommits`, so skip it.
 		return
 	}
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    opType,
@@ -365,17 +360,17 @@ func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model
 		IsPrivate: repo.IsPrivate,
 		RefName:   refFullName,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func (a *actionNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 	opType := activities_model.ActionDeleteBranch
 	if refType == "tag" {
 		// has sent same action in `NotifyPushCommits`, so skip it.
 		return
 	}
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: doer.ID,
 		ActUser:   doer,
 		OpType:    opType,
@@ -384,20 +379,20 @@ func (a *actionNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model
 		IsPrivate: repo.IsPrivate,
 		RefName:   refFullName,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (a *actionNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	data, err := json.Marshal(commits)
 	if err != nil {
 		log.Error("json.Marshal: %v", err)
 		return
 	}
 
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: repo.OwnerID,
-		ActUser:   repo.MustOwner(),
+		ActUser:   repo.MustOwner(ctx),
 		OpType:    activities_model.ActionMirrorSyncPush,
 		RepoID:    repo.ID,
 		Repo:      repo,
@@ -405,44 +400,44 @@ func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *re
 		RefName:   opts.RefFullName,
 		Content:   string(data),
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: repo.OwnerID,
-		ActUser:   repo.MustOwner(),
+		ActUser:   repo.MustOwner(ctx),
 		OpType:    activities_model.ActionMirrorSyncCreate,
 		RepoID:    repo.ID,
 		Repo:      repo,
 		IsPrivate: repo.IsPrivate,
 		RefName:   refFullName,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+func (a *actionNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: repo.OwnerID,
-		ActUser:   repo.MustOwner(),
+		ActUser:   repo.MustOwner(ctx),
 		OpType:    activities_model.ActionMirrorSyncDelete,
 		RepoID:    repo.ID,
 		Repo:      repo,
 		IsPrivate: repo.IsPrivate,
 		RefName:   refFullName,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
 
-func (a *actionNotifier) NotifyNewRelease(rel *repo_model.Release) {
-	if err := rel.LoadAttributes(); err != nil {
-		log.Error("NotifyNewRelease: %v", err)
+func (a *actionNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
+	if err := rel.LoadAttributes(ctx); err != nil {
+		log.Error("LoadAttributes: %v", err)
 		return
 	}
-	if err := activities_model.NotifyWatchers(&activities_model.Action{
+	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
 		ActUserID: rel.PublisherID,
 		ActUser:   rel.Publisher,
 		OpType:    activities_model.ActionPublishRelease,
@@ -452,6 +447,6 @@ func (a *actionNotifier) NotifyNewRelease(rel *repo_model.Release) {
 		Content:   rel.Title,
 		RefName:   rel.TagName,
 	}); err != nil {
-		log.Error("notifyWatchers: %v", err)
+		log.Error("NotifyWatchers: %v", err)
 	}
 }
diff --git a/modules/notification/action/action_test.go b/modules/notification/action/action_test.go
index 79a938d6c..dc31b3189 100644
--- a/modules/notification/action/action_test.go
+++ b/modules/notification/action/action_test.go
@@ -10,6 +10,7 @@ import (
 	"testing"
 
 	activities_model "code.gitea.io/gitea/models/activities"
+	"code.gitea.io/gitea/models/db"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
@@ -46,7 +47,7 @@ func TestRenameRepoAction(t *testing.T) {
 	}
 	unittest.AssertNotExistsBean(t, actionBean)
 
-	NewNotifier().NotifyRenameRepository(user, repo, oldRepoName)
+	NewNotifier().NotifyRenameRepository(db.DefaultContext, user, repo, oldRepoName)
 
 	unittest.AssertExistsAndLoadBean(t, actionBean)
 	unittest.CheckConsistencyFor(t, &activities_model.Action{})
diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go
index 9edab8213..2f7deac88 100644
--- a/modules/notification/base/notifier.go
+++ b/modules/notification/base/notifier.go
@@ -5,6 +5,8 @@
 package base
 
 import (
+	"context"
+
 	issues_model "code.gitea.io/gitea/models/issues"
 	packages_model "code.gitea.io/gitea/models/packages"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -15,50 +17,50 @@ import (
 // Notifier defines an interface to notify receiver
 type Notifier interface {
 	Run()
-	NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository)
-	NotifyMigrateRepository(doer, u *user_model.User, repo *repo_model.Repository)
-	NotifyDeleteRepository(doer *user_model.User, repo *repo_model.Repository)
-	NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository)
-	NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string)
-	NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string)
-	NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User)
-	NotifyIssueChangeStatus(*user_model.User, *issues_model.Issue, *issues_model.Comment, bool)
-	NotifyDeleteIssue(*user_model.User, *issues_model.Issue)
-	NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64)
-	NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment)
-	NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment)
-	NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string)
-	NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue)
-	NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string)
-	NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string)
-	NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue,
+	NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository)
+	NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository)
+	NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository)
+	NotifyForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository)
+	NotifyRenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldRepoName string)
+	NotifyTransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string)
+	NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User)
+	NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool)
+	NotifyDeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue)
+	NotifyIssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64)
+	NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment)
+	NotifyPullReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment)
+	NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string)
+	NotifyIssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue)
+	NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string)
+	NotifyIssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string)
+	NotifyIssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
 		addedLabels, removedLabels []*issues_model.Label)
-	NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User)
-	NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User)
-	NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User)
-	NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest)
-	NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User)
-	NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User)
-	NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string)
-	NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment)
-	NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment)
-	NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+	NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User)
+	NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
+	NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
+	NotifyPullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
+	NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User)
+	NotifyPullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User)
+	NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string)
+	NotifyPullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment)
+	NotifyPullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment)
+	NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 		issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User)
-	NotifyUpdateComment(*user_model.User, *issues_model.Comment, string)
-	NotifyDeleteComment(*user_model.User, *issues_model.Comment)
-	NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string)
-	NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string)
-	NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string)
-	NotifyNewRelease(rel *repo_model.Release)
-	NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release)
-	NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release)
-	NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits)
-	NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string)
-	NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string)
-	NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits)
-	NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string)
-	NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string)
-	NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository)
-	NotifyPackageCreate(doer *user_model.User, pd *packages_model.PackageDescriptor)
-	NotifyPackageDelete(doer *user_model.User, pd *packages_model.PackageDescriptor)
+	NotifyUpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string)
+	NotifyDeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment)
+	NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string)
+	NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string)
+	NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string)
+	NotifyNewRelease(ctx context.Context, rel *repo_model.Release)
+	NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release)
+	NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release)
+	NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits)
+	NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string)
+	NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string)
+	NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits)
+	NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string)
+	NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string)
+	NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository)
+	NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor)
+	NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor)
 }
diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go
index f051fbc26..88e0c93de 100644
--- a/modules/notification/base/null.go
+++ b/modules/notification/base/null.go
@@ -5,6 +5,8 @@
 package base
 
 import (
+	"context"
+
 	issues_model "code.gitea.io/gitea/models/issues"
 	packages_model "code.gitea.io/gitea/models/packages"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -22,179 +24,179 @@ func (*NullNotifier) Run() {
 }
 
 // NotifyCreateIssueComment places a place holder function
-func (*NullNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (*NullNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) {
 }
 
 // NotifyNewIssue places a place holder function
-func (*NullNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
+func (*NullNotifier) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
 }
 
 // NotifyIssueChangeStatus places a place holder function
-func (*NullNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
+func (*NullNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
 }
 
 // NotifyDeleteIssue notify when some issue deleted
-func (*NullNotifier) NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) {
+func (*NullNotifier) NotifyDeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
 }
 
 // NotifyNewPullRequest places a place holder function
-func (*NullNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) {
+func (*NullNotifier) NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
 }
 
 // NotifyPullRequestReview places a place holder function
-func (*NullNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
+func (*NullNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
 }
 
 // NotifyPullRequestCodeComment places a place holder function
-func (*NullNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
+func (*NullNotifier) NotifyPullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
 }
 
 // NotifyMergePullRequest places a place holder function
-func (*NullNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func (*NullNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 }
 
 // NotifyAutoMergePullRequest places a place holder function
-func (*NullNotifier) NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func (*NullNotifier) NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 }
 
 // NotifyPullRequestSynchronized places a place holder function
-func (*NullNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) {
+func (*NullNotifier) NotifyPullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 }
 
 // NotifyPullRequestChangeTargetBranch places a place holder function
-func (*NullNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
+func (*NullNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
 }
 
 // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch
-func (*NullNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
+func (*NullNotifier) NotifyPullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
 }
 
-// NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin
-func (*NullNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
+// NotifyPullReviewDismiss notifies when a review was dismissed by repo admin
+func (*NullNotifier) NotifyPullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
 }
 
 // NotifyUpdateComment places a place holder function
-func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) {
+func (*NullNotifier) NotifyUpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) {
 }
 
 // NotifyDeleteComment places a place holder function
-func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) {
+func (*NullNotifier) NotifyDeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) {
 }
 
 // NotifyNewWikiPage places a place holder function
-func (*NullNotifier) NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func (*NullNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 }
 
 // NotifyEditWikiPage places a place holder function
-func (*NullNotifier) NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func (*NullNotifier) NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 }
 
 // NotifyDeleteWikiPage places a place holder function
-func (*NullNotifier) NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) {
+func (*NullNotifier) NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) {
 }
 
 // NotifyNewRelease places a place holder function
-func (*NullNotifier) NotifyNewRelease(rel *repo_model.Release) {
+func (*NullNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
 }
 
 // NotifyUpdateRelease places a place holder function
-func (*NullNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) {
+func (*NullNotifier) NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
 }
 
 // NotifyDeleteRelease places a place holder function
-func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) {
+func (*NullNotifier) NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
 }
 
 // NotifyIssueChangeMilestone places a place holder function
-func (*NullNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
+func (*NullNotifier) NotifyIssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
 }
 
 // NotifyIssueChangeContent places a place holder function
-func (*NullNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) {
+func (*NullNotifier) NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
 }
 
 // NotifyIssueChangeAssignee places a place holder function
-func (*NullNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
+func (*NullNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 }
 
 // NotifyPullReviewRequest places a place holder function
-func (*NullNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
+func (*NullNotifier) NotifyPullReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 }
 
 // NotifyIssueClearLabels places a place holder function
-func (*NullNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) {
+func (*NullNotifier) NotifyIssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
 }
 
 // NotifyIssueChangeTitle places a place holder function
-func (*NullNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+func (*NullNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
 }
 
 // NotifyIssueChangeRef places a place holder function
-func (*NullNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+func (*NullNotifier) NotifyIssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
 }
 
 // NotifyIssueChangeLabels places a place holder function
-func (*NullNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue,
+func (*NullNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
 	addedLabels, removedLabels []*issues_model.Label) {
 }
 
 // NotifyCreateRepository places a place holder function
-func (*NullNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func (*NullNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 }
 
 // NotifyDeleteRepository places a place holder function
-func (*NullNotifier) NotifyDeleteRepository(doer *user_model.User, repo *repo_model.Repository) {
+func (*NullNotifier) NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
 }
 
 // NotifyForkRepository places a place holder function
-func (*NullNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) {
+func (*NullNotifier) NotifyForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
 }
 
 // NotifyMigrateRepository places a place holder function
-func (*NullNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func (*NullNotifier) NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 }
 
 // NotifyPushCommits notifies commits pushed to notifiers
-func (*NullNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (*NullNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 }
 
 // NotifyCreateRef notifies branch or tag creation to notifiers
-func (*NullNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func (*NullNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 }
 
 // NotifyDeleteRef notifies branch or tag deletion to notifiers
-func (*NullNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func (*NullNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 }
 
 // NotifyRenameRepository places a place holder function
-func (*NullNotifier) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) {
+func (*NullNotifier) NotifyRenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldRepoName string) {
 }
 
 // NotifyTransferRepository places a place holder function
-func (*NullNotifier) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
+func (*NullNotifier) NotifyTransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
 }
 
 // NotifySyncPushCommits places a place holder function
-func (*NullNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (*NullNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 }
 
 // NotifySyncCreateRef places a place holder function
-func (*NullNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func (*NullNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 }
 
 // NotifySyncDeleteRef places a place holder function
-func (*NullNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func (*NullNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 }
 
 // NotifyRepoPendingTransfer places a place holder function
-func (*NullNotifier) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) {
+func (*NullNotifier) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
 }
 
 // NotifyPackageCreate places a place holder function
-func (*NullNotifier) NotifyPackageCreate(doer *user_model.User, pd *packages_model.PackageDescriptor) {
+func (*NullNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
 }
 
 // NotifyPackageDelete places a place holder function
-func (*NullNotifier) NotifyPackageDelete(doer *user_model.User, pd *packages_model.PackageDescriptor) {
+func (*NullNotifier) NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
 }
diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go
index fc9afdd4b..2bacd5dec 100644
--- a/modules/notification/indexer/indexer.go
+++ b/modules/notification/indexer/indexer.go
@@ -5,6 +5,8 @@
 package indexer
 
 import (
+	"context"
+
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
@@ -29,13 +31,13 @@ func NewNotifier() base.Notifier {
 	return &indexerNotifier{}
 }
 
-func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (r *indexerNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
 	if comment.Type == issues_model.CommentTypeComment {
 		if issue.Comments == nil {
-			if err := issue.LoadDiscussComments(); err != nil {
-				log.Error("LoadComments failed: %v", err)
+			if err := issue.LoadDiscussComments(ctx); err != nil {
+				log.Error("LoadDiscussComments failed: %v", err)
 				return
 			}
 		} else {
@@ -46,15 +48,15 @@ func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *
 	}
 }
 
-func (r *indexerNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
+func (r *indexerNotifier) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
 	issue_indexer.UpdateIssueIndexer(issue)
 }
 
-func (r *indexerNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) {
+func (r *indexerNotifier) NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
 	issue_indexer.UpdateIssueIndexer(pr.Issue)
 }
 
-func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) {
+func (r *indexerNotifier) NotifyUpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) {
 	if c.Type == issues_model.CommentTypeComment {
 		var found bool
 		if c.Issue.Comments != nil {
@@ -68,8 +70,8 @@ func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_m
 		}
 
 		if !found {
-			if err := c.Issue.LoadDiscussComments(); err != nil {
-				log.Error("LoadComments failed: %v", err)
+			if err := c.Issue.LoadDiscussComments(ctx); err != nil {
+				log.Error("LoadDiscussComments failed: %v", err)
 				return
 			}
 		}
@@ -78,9 +80,9 @@ func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_m
 	}
 }
 
-func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) {
+func (r *indexerNotifier) NotifyDeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) {
 	if comment.Type == issues_model.CommentTypeComment {
-		if err := comment.LoadIssue(); err != nil {
+		if err := comment.LoadIssue(ctx); err != nil {
 			log.Error("LoadIssue: %v", err)
 			return
 		}
@@ -97,8 +99,8 @@ func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *is
 		}
 
 		if !found {
-			if err := comment.Issue.LoadDiscussComments(); err != nil {
-				log.Error("LoadComments failed: %v", err)
+			if err := comment.Issue.LoadDiscussComments(ctx); err != nil {
+				log.Error("LoadDiscussComments failed: %v", err)
 				return
 			}
 		}
@@ -107,15 +109,15 @@ func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *is
 	}
 }
 
-func (r *indexerNotifier) NotifyDeleteRepository(doer *user_model.User, repo *repo_model.Repository) {
-	issue_indexer.DeleteRepoIssueIndexer(repo)
+func (r *indexerNotifier) NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
+	issue_indexer.DeleteRepoIssueIndexer(ctx, repo)
 	if setting.Indexer.RepoIndexerEnabled {
 		code_indexer.UpdateRepoIndexer(repo)
 	}
 }
 
-func (r *indexerNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
-	issue_indexer.UpdateRepoIndexer(repo)
+func (r *indexerNotifier) NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
+	issue_indexer.UpdateRepoIndexer(ctx, repo)
 	if setting.Indexer.RepoIndexerEnabled && !repo.IsEmpty {
 		code_indexer.UpdateRepoIndexer(repo)
 	}
@@ -124,7 +126,7 @@ func (r *indexerNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo
 	}
 }
 
-func (r *indexerNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	if setting.Indexer.RepoIndexerEnabled && opts.RefFullName == git.BranchPrefix+repo.DefaultBranch {
 		code_indexer.UpdateRepoIndexer(repo)
 	}
@@ -133,7 +135,7 @@ func (r *indexerNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_
 	}
 }
 
-func (r *indexerNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func (r *indexerNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	if setting.Indexer.RepoIndexerEnabled && opts.RefFullName == git.BranchPrefix+repo.DefaultBranch {
 		code_indexer.UpdateRepoIndexer(repo)
 	}
@@ -142,14 +144,14 @@ func (r *indexerNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *r
 	}
 }
 
-func (r *indexerNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) {
+func (r *indexerNotifier) NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
 	issue_indexer.UpdateIssueIndexer(issue)
 }
 
-func (r *indexerNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+func (r *indexerNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
 	issue_indexer.UpdateIssueIndexer(issue)
 }
 
-func (r *indexerNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) {
+func (r *indexerNotifier) NotifyIssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) {
 	issue_indexer.UpdateIssueIndexer(issue)
 }
diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go
index 54f561839..123fa0e65 100644
--- a/modules/notification/mail/mail.go
+++ b/modules/notification/mail/mail.go
@@ -5,16 +5,15 @@
 package mail
 
 import (
+	"context"
 	"fmt"
 
 	activities_model "code.gitea.io/gitea/models/activities"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
-	"code.gitea.io/gitea/modules/graceful"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/notification/base"
-	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/services/mailer"
 )
 
@@ -29,12 +28,9 @@ func NewNotifier() base.Notifier {
 	return &mailNotifier{}
 }
 
-func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (m *mailNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
 	var act activities_model.ActionType
 	if comment.Type == issues_model.CommentTypeClose {
 		act = activities_model.ActionCloseIssue
@@ -53,13 +49,13 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep
 	}
 }
 
-func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
-	if err := mailer.MailParticipants(issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil {
+func (m *mailNotifier) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
+	if err := mailer.MailParticipants(ctx, issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil {
 		log.Error("MailParticipants: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
+func (m *mailNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
 	var actionType activities_model.ActionType
 	if issue.IsPull {
 		if isClosed {
@@ -75,33 +71,30 @@ func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *iss
 		}
 	}
 
-	if err := mailer.MailParticipants(issue, doer, actionType, nil); err != nil {
+	if err := mailer.MailParticipants(ctx, issue, doer, actionType, nil); err != nil {
 		log.Error("MailParticipants: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
-	if err := issue.LoadPullRequest(); err != nil {
+func (m *mailNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+	if err := issue.LoadPullRequest(ctx); err != nil {
 		log.Error("issue.LoadPullRequest: %v", err)
 		return
 	}
 	if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() {
-		if err := mailer.MailParticipants(issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil {
+		if err := mailer.MailParticipants(ctx, issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil {
 			log.Error("MailParticipants: %v", err)
 		}
 	}
 }
 
-func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) {
-	if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil {
+func (m *mailNotifier) NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
+	if err := mailer.MailParticipants(ctx, pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil {
 		log.Error("MailParticipants: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
+func (m *mailNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
 	var act activities_model.ActionType
 	if comment.Type == issues_model.CommentTypeClose {
 		act = activities_model.ActionCloseIssue
@@ -115,60 +108,54 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *
 	}
 }
 
-func (m *mailNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestCodeComment Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
+func (m *mailNotifier) NotifyPullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
 	if err := mailer.MailMentionsComment(ctx, pr, comment, mentions); err != nil {
 		log.Error("MailMentionsComment: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
+func (m *mailNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 	// mail only sent to added assignees and not self-assignee
 	if !removed && doer.ID != assignee.ID && assignee.EmailNotifications() != user_model.EmailNotificationsDisabled {
 		ct := fmt.Sprintf("Assigned #%d.", issue.Index)
-		if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{assignee}); err != nil {
+		if err := mailer.SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{assignee}); err != nil {
 			log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err)
 		}
 	}
 }
 
-func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
+func (m *mailNotifier) NotifyPullReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 	if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotifications() != user_model.EmailNotificationsDisabled {
 		ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL())
-		if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil {
+		if err := mailer.SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil {
 			log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err)
 		}
 	}
 }
 
-func (m *mailNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	if err := pr.LoadIssue(); err != nil {
-		log.Error("pr.LoadIssue: %v", err)
+func (m *mailNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	if err := pr.LoadIssue(ctx); err != nil {
+		log.Error("LoadIssue: %v", err)
 		return
 	}
-	if err := mailer.MailParticipants(pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil {
+	if err := mailer.MailParticipants(ctx, pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil {
 		log.Error("MailParticipants: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	if err := pr.LoadIssue(); err != nil {
+func (m *mailNotifier) NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	if err := pr.LoadIssue(ctx); err != nil {
 		log.Error("pr.LoadIssue: %v", err)
 		return
 	}
-	if err := mailer.MailParticipants(pr.Issue, doer, activities_model.ActionAutoMergePullRequest, nil); err != nil {
+	if err := mailer.MailParticipants(ctx, pr.Issue, doer, activities_model.ActionAutoMergePullRequest, nil); err != nil {
 		log.Error("MailParticipants: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestPushCommits Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
+func (m *mailNotifier) NotifyPullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
 	var err error
-	if err = comment.LoadIssue(); err != nil {
+	if err = comment.LoadIssue(ctx); err != nil {
 		log.Error("comment.LoadIssue: %v", err)
 		return
 	}
@@ -176,35 +163,29 @@ func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *i
 		log.Error("comment.Issue.LoadRepo: %v", err)
 		return
 	}
-	if err = comment.Issue.LoadPullRequest(); err != nil {
+	if err = comment.Issue.LoadPullRequest(ctx); err != nil {
 		log.Error("comment.Issue.LoadPullRequest: %v", err)
 		return
 	}
-	if err = comment.Issue.PullRequest.LoadBaseRepoCtx(ctx); err != nil {
+	if err = comment.Issue.PullRequest.LoadBaseRepo(ctx); err != nil {
 		log.Error("comment.Issue.PullRequest.LoadBaseRepo: %v", err)
 		return
 	}
 	if err := comment.LoadPushCommits(ctx); err != nil {
 		log.Error("comment.LoadPushCommits: %v", err)
 	}
-	m.NotifyCreateIssueComment(doer, comment.Issue.Repo, comment.Issue, comment, nil)
+	m.NotifyCreateIssueComment(ctx, doer, comment.Issue.Repo, comment.Issue, comment, nil)
 }
 
-func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID))
-	defer finished()
-
+func (m *mailNotifier) NotifyPullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
 	if err := mailer.MailParticipantsComment(ctx, comment, activities_model.ActionPullReviewDismissed, review.Issue, nil); err != nil {
 		log.Error("MailParticipantsComment: %v", err)
 	}
 }
 
-func (m *mailNotifier) NotifyNewRelease(rel *repo_model.Release) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyNewRelease rel[%d]%s in [%d]", rel.ID, rel.Title, rel.RepoID))
-	defer finished()
-
-	if err := rel.LoadAttributes(); err != nil {
-		log.Error("NotifyNewRelease: %v", err)
+func (m *mailNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
+	if err := rel.LoadAttributes(ctx); err != nil {
+		log.Error("LoadAttributes: %v", err)
 		return
 	}
 
@@ -215,8 +196,8 @@ func (m *mailNotifier) NotifyNewRelease(rel *repo_model.Release) {
 	mailer.MailNewRelease(ctx, rel)
 }
 
-func (m *mailNotifier) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) {
-	if err := mailer.SendRepoTransferNotifyMail(doer, newOwner, repo); err != nil {
-		log.Error("NotifyRepoPendingTransfer: %v", err)
+func (m *mailNotifier) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
+	if err := mailer.SendRepoTransferNotifyMail(ctx, doer, newOwner, repo); err != nil {
+		log.Error("SendRepoTransferNotifyMail: %v", err)
 	}
 }
diff --git a/modules/notification/mirror/mirror.go b/modules/notification/mirror/mirror.go
index 646b09a4a..159c44ee6 100644
--- a/modules/notification/mirror/mirror.go
+++ b/modules/notification/mirror/mirror.go
@@ -5,6 +5,8 @@
 package mirror
 
 import (
+	"context"
+
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/log"
@@ -24,16 +26,16 @@ func NewNotifier() base.Notifier {
 	return &mirrorNotifier{}
 }
 
-func (m *mirrorNotifier) NotifyPushCommits(_ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) {
-	syncPushMirrorWithSyncOnCommit(repo.ID)
+func (m *mirrorNotifier) NotifyPushCommits(ctx context.Context, _ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) {
+	syncPushMirrorWithSyncOnCommit(ctx, repo.ID)
 }
 
-func (m *mirrorNotifier) NotifySyncPushCommits(_ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) {
-	syncPushMirrorWithSyncOnCommit(repo.ID)
+func (m *mirrorNotifier) NotifySyncPushCommits(ctx context.Context, _ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) {
+	syncPushMirrorWithSyncOnCommit(ctx, repo.ID)
 }
 
-func syncPushMirrorWithSyncOnCommit(repoID int64) {
-	pushMirrors, err := repo_model.GetPushMirrorsSyncedOnCommit(repoID)
+func syncPushMirrorWithSyncOnCommit(ctx context.Context, repoID int64) {
+	pushMirrors, err := repo_model.GetPushMirrorsSyncedOnCommit(ctx, repoID)
 	if err != nil {
 		log.Error("repo_model.GetPushMirrorsSyncedOnCommit failed: %v", err)
 		return
diff --git a/modules/notification/notification.go b/modules/notification/notification.go
index 7bdc0a04c..a117a6081 100644
--- a/modules/notification/notification.go
+++ b/modules/notification/notification.go
@@ -5,6 +5,8 @@
 package notification
 
 import (
+	"context"
+
 	issues_model "code.gitea.io/gitea/models/issues"
 	packages_model "code.gitea.io/gitea/models/packages"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -41,313 +43,313 @@ func NewContext() {
 }
 
 // NotifyNewWikiPage notifies creating new wiki pages to notifiers
-func NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyNewWikiPage(doer, repo, page, comment)
+		notifier.NotifyNewWikiPage(ctx, doer, repo, page, comment)
 	}
 }
 
 // NotifyEditWikiPage notifies editing or renaming wiki pages to notifiers
-func NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyEditWikiPage(doer, repo, page, comment)
+		notifier.NotifyEditWikiPage(ctx, doer, repo, page, comment)
 	}
 }
 
 // NotifyDeleteWikiPage notifies deleting wiki pages to notifiers
-func NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) {
+func NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteWikiPage(doer, repo, page)
+		notifier.NotifyDeleteWikiPage(ctx, doer, repo, page)
 	}
 }
 
 // NotifyCreateIssueComment notifies issue comment related message to notifiers
-func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
 	for _, notifier := range notifiers {
-		notifier.NotifyCreateIssueComment(doer, repo, issue, comment, mentions)
+		notifier.NotifyCreateIssueComment(ctx, doer, repo, issue, comment, mentions)
 	}
 }
 
 // NotifyNewIssue notifies new issue to notifiers
-func NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
+func NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
 	for _, notifier := range notifiers {
-		notifier.NotifyNewIssue(issue, mentions)
+		notifier.NotifyNewIssue(ctx, issue, mentions)
 	}
 }
 
 // NotifyIssueChangeStatus notifies close or reopen issue to notifiers
-func NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
+func NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeStatus(doer, issue, actionComment, closeOrReopen)
+		notifier.NotifyIssueChangeStatus(ctx, doer, issue, actionComment, closeOrReopen)
 	}
 }
 
 // NotifyDeleteIssue notify when some issue deleted
-func NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) {
+func NotifyDeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteIssue(doer, issue)
+		notifier.NotifyDeleteIssue(ctx, doer, issue)
 	}
 }
 
 // NotifyMergePullRequest notifies merge pull request to notifiers
-func NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	for _, notifier := range notifiers {
-		notifier.NotifyMergePullRequest(pr, doer)
+		notifier.NotifyMergePullRequest(ctx, doer, pr)
 	}
 }
 
 // NotifyAutoMergePullRequest notifies merge pull request to notifiers
-func NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	for _, notifier := range notifiers {
-		notifier.NotifyAutoMergePullRequest(pr, doer)
+		notifier.NotifyAutoMergePullRequest(ctx, doer, pr)
 	}
 }
 
 // NotifyNewPullRequest notifies new pull request to notifiers
-func NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) {
+func NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
 	for _, notifier := range notifiers {
-		notifier.NotifyNewPullRequest(pr, mentions)
+		notifier.NotifyNewPullRequest(ctx, pr, mentions)
 	}
 }
 
 // NotifyPullRequestSynchronized notifies Synchronized pull request
-func NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) {
+func NotifyPullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRequestSynchronized(doer, pr)
+		notifier.NotifyPullRequestSynchronized(ctx, doer, pr)
 	}
 }
 
 // NotifyPullRequestReview notifies new pull request review
-func NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
+func NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRequestReview(pr, review, comment, mentions)
+		notifier.NotifyPullRequestReview(ctx, pr, review, comment, mentions)
 	}
 }
 
 // NotifyPullRequestCodeComment notifies new pull request code comment
-func NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
+func NotifyPullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRequestCodeComment(pr, comment, mentions)
+		notifier.NotifyPullRequestCodeComment(ctx, pr, comment, mentions)
 	}
 }
 
 // NotifyPullRequestChangeTargetBranch notifies when a pull request's target branch was changed
-func NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
+func NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRequestChangeTargetBranch(doer, pr, oldBranch)
+		notifier.NotifyPullRequestChangeTargetBranch(ctx, doer, pr, oldBranch)
 	}
 }
 
 // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch
-func NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
+func NotifyPullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRequestPushCommits(doer, pr, comment)
+		notifier.NotifyPullRequestPushCommits(ctx, doer, pr, comment)
 	}
 }
 
-// NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin
-func NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
+// NotifyPullReviewDismiss notifies when a review was dismissed by repo admin
+func NotifyPullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullRevieweDismiss(doer, review, comment)
+		notifier.NotifyPullReviewDismiss(ctx, doer, review, comment)
 	}
 }
 
 // NotifyUpdateComment notifies update comment to notifiers
-func NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) {
+func NotifyUpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyUpdateComment(doer, c, oldContent)
+		notifier.NotifyUpdateComment(ctx, doer, c, oldContent)
 	}
 }
 
 // NotifyDeleteComment notifies delete comment to notifiers
-func NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) {
+func NotifyDeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteComment(doer, c)
+		notifier.NotifyDeleteComment(ctx, doer, c)
 	}
 }
 
 // NotifyNewRelease notifies new release to notifiers
-func NotifyNewRelease(rel *repo_model.Release) {
+func NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
 	for _, notifier := range notifiers {
-		notifier.NotifyNewRelease(rel)
+		notifier.NotifyNewRelease(ctx, rel)
 	}
 }
 
 // NotifyUpdateRelease notifies update release to notifiers
-func NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) {
+func NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
 	for _, notifier := range notifiers {
-		notifier.NotifyUpdateRelease(doer, rel)
+		notifier.NotifyUpdateRelease(ctx, doer, rel)
 	}
 }
 
 // NotifyDeleteRelease notifies delete release to notifiers
-func NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) {
+func NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteRelease(doer, rel)
+		notifier.NotifyDeleteRelease(ctx, doer, rel)
 	}
 }
 
 // NotifyIssueChangeMilestone notifies change milestone to notifiers
-func NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
+func NotifyIssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeMilestone(doer, issue, oldMilestoneID)
+		notifier.NotifyIssueChangeMilestone(ctx, doer, issue, oldMilestoneID)
 	}
 }
 
 // NotifyIssueChangeContent notifies change content to notifiers
-func NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) {
+func NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeContent(doer, issue, oldContent)
+		notifier.NotifyIssueChangeContent(ctx, doer, issue, oldContent)
 	}
 }
 
 // NotifyIssueChangeAssignee notifies change content to notifiers
-func NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
+func NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeAssignee(doer, issue, assignee, removed, comment)
+		notifier.NotifyIssueChangeAssignee(ctx, doer, issue, assignee, removed, comment)
 	}
 }
 
 // NotifyPullReviewRequest notifies Request Review change
-func NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
+func NotifyPullReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPullReviewRequest(doer, issue, reviewer, isRequest, comment)
+		notifier.NotifyPullReviewRequest(ctx, doer, issue, reviewer, isRequest, comment)
 	}
 }
 
 // NotifyIssueClearLabels notifies clear labels to notifiers
-func NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) {
+func NotifyIssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueClearLabels(doer, issue)
+		notifier.NotifyIssueClearLabels(ctx, doer, issue)
 	}
 }
 
 // NotifyIssueChangeTitle notifies change title to notifiers
-func NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+func NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeTitle(doer, issue, oldTitle)
+		notifier.NotifyIssueChangeTitle(ctx, doer, issue, oldTitle)
 	}
 }
 
 // NotifyIssueChangeRef notifies change reference to notifiers
-func NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) {
+func NotifyIssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeRef(doer, issue, oldRef)
+		notifier.NotifyIssueChangeRef(ctx, doer, issue, oldRef)
 	}
 }
 
 // NotifyIssueChangeLabels notifies change labels to notifiers
-func NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue,
+func NotifyIssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
 	addedLabels, removedLabels []*issues_model.Label,
 ) {
 	for _, notifier := range notifiers {
-		notifier.NotifyIssueChangeLabels(doer, issue, addedLabels, removedLabels)
+		notifier.NotifyIssueChangeLabels(ctx, doer, issue, addedLabels, removedLabels)
 	}
 }
 
 // NotifyCreateRepository notifies create repository to notifiers
-func NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 	for _, notifier := range notifiers {
-		notifier.NotifyCreateRepository(doer, u, repo)
+		notifier.NotifyCreateRepository(ctx, doer, u, repo)
 	}
 }
 
 // NotifyMigrateRepository notifies create repository to notifiers
-func NotifyMigrateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 	for _, notifier := range notifiers {
-		notifier.NotifyMigrateRepository(doer, u, repo)
+		notifier.NotifyMigrateRepository(ctx, doer, u, repo)
 	}
 }
 
 // NotifyTransferRepository notifies create repository to notifiers
-func NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, newOwnerName string) {
+func NotifyTransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, newOwnerName string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyTransferRepository(doer, repo, newOwnerName)
+		notifier.NotifyTransferRepository(ctx, doer, repo, newOwnerName)
 	}
 }
 
 // NotifyDeleteRepository notifies delete repository to notifiers
-func NotifyDeleteRepository(doer *user_model.User, repo *repo_model.Repository) {
+func NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteRepository(doer, repo)
+		notifier.NotifyDeleteRepository(ctx, doer, repo)
 	}
 }
 
 // NotifyForkRepository notifies fork repository to notifiers
-func NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) {
+func NotifyForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
 	for _, notifier := range notifiers {
-		notifier.NotifyForkRepository(doer, oldRepo, repo)
+		notifier.NotifyForkRepository(ctx, doer, oldRepo, repo)
 	}
 }
 
 // NotifyRenameRepository notifies repository renamed
-func NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldName string) {
+func NotifyRenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldName string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyRenameRepository(doer, repo, oldName)
+		notifier.NotifyRenameRepository(ctx, doer, repo, oldName)
 	}
 }
 
 // NotifyPushCommits notifies commits pushed to notifiers
-func NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPushCommits(pusher, repo, opts, commits)
+		notifier.NotifyPushCommits(ctx, pusher, repo, opts, commits)
 	}
 }
 
 // NotifyCreateRef notifies branch or tag creation to notifiers
-func NotifyCreateRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyCreateRef(pusher, repo, refType, refFullName, refID)
+		notifier.NotifyCreateRef(ctx, pusher, repo, refType, refFullName, refID)
 	}
 }
 
 // NotifyDeleteRef notifies branch or tag deletion to notifiers
-func NotifyDeleteRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 	for _, notifier := range notifiers {
-		notifier.NotifyDeleteRef(pusher, repo, refType, refFullName)
+		notifier.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName)
 	}
 }
 
 // NotifySyncPushCommits notifies commits pushed to notifiers
-func NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+func NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	for _, notifier := range notifiers {
-		notifier.NotifySyncPushCommits(pusher, repo, opts, commits)
+		notifier.NotifySyncPushCommits(ctx, pusher, repo, opts, commits)
 	}
 }
 
 // NotifySyncCreateRef notifies branch or tag creation to notifiers
-func NotifySyncCreateRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 	for _, notifier := range notifiers {
-		notifier.NotifySyncCreateRef(pusher, repo, refType, refFullName, refID)
+		notifier.NotifySyncCreateRef(ctx, pusher, repo, refType, refFullName, refID)
 	}
 }
 
 // NotifySyncDeleteRef notifies branch or tag deletion to notifiers
-func NotifySyncDeleteRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 	for _, notifier := range notifiers {
-		notifier.NotifySyncDeleteRef(pusher, repo, refType, refFullName)
+		notifier.NotifySyncDeleteRef(ctx, pusher, repo, refType, refFullName)
 	}
 }
 
 // NotifyRepoPendingTransfer notifies creation of pending transfer to notifiers
-func NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) {
+func NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
 	for _, notifier := range notifiers {
-		notifier.NotifyRepoPendingTransfer(doer, newOwner, repo)
+		notifier.NotifyRepoPendingTransfer(ctx, doer, newOwner, repo)
 	}
 }
 
 // NotifyPackageCreate notifies creation of a package to notifiers
-func NotifyPackageCreate(doer *user_model.User, pd *packages_model.PackageDescriptor) {
+func NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPackageCreate(doer, pd)
+		notifier.NotifyPackageCreate(ctx, doer, pd)
 	}
 }
 
 // NotifyPackageDelete notifies deletion of a package to notifiers
-func NotifyPackageDelete(doer *user_model.User, pd *packages_model.PackageDescriptor) {
+func NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
 	for _, notifier := range notifiers {
-		notifier.NotifyPackageDelete(doer, pd)
+		notifier.NotifyPackageDelete(ctx, doer, pd)
 	}
 }
diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go
index 0e2b3e67c..a38289c97 100644
--- a/modules/notification/ui/ui.go
+++ b/modules/notification/ui/ui.go
@@ -5,6 +5,8 @@
 package ui
 
 import (
+	"context"
+
 	activities_model "code.gitea.io/gitea/models/activities"
 	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
@@ -54,7 +56,7 @@ func (ns *notificationService) Run() {
 	graceful.GetManager().RunWithShutdownFns(ns.issueQueue.Run)
 }
 
-func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (ns *notificationService) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
 	opts := issueNotificationOpts{
@@ -78,7 +80,7 @@ func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, r
 	}
 }
 
-func (ns *notificationService) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
+func (ns *notificationService) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
 	_ = ns.issueQueue.Push(issueNotificationOpts{
 		IssueID:              issue.ID,
 		NotificationAuthorID: issue.Poster.ID,
@@ -92,15 +94,15 @@ func (ns *notificationService) NotifyNewIssue(issue *issues_model.Issue, mention
 	}
 }
 
-func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
+func (ns *notificationService) NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
 	_ = ns.issueQueue.Push(issueNotificationOpts{
 		IssueID:              issue.ID,
 		NotificationAuthorID: doer.ID,
 	})
 }
 
-func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
-	if err := issue.LoadPullRequest(); err != nil {
+func (ns *notificationService) NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+	if err := issue.LoadPullRequest(ctx); err != nil {
 		log.Error("issue.LoadPullRequest: %v", err)
 		return
 	}
@@ -112,24 +114,24 @@ func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, iss
 	}
 }
 
-func (ns *notificationService) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func (ns *notificationService) NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	_ = ns.issueQueue.Push(issueNotificationOpts{
 		IssueID:              pr.Issue.ID,
 		NotificationAuthorID: doer.ID,
 	})
 }
 
-func (ns *notificationService) NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	ns.NotifyMergePullRequest(pr, doer)
+func (ns *notificationService) NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	ns.NotifyMergePullRequest(ctx, doer, pr)
 }
 
-func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) {
-	if err := pr.LoadIssue(); err != nil {
+func (ns *notificationService) NotifyNewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
+	if err := pr.LoadIssue(ctx); err != nil {
 		log.Error("Unable to load issue: %d for pr: %d: Error: %v", pr.IssueID, pr.ID, err)
 		return
 	}
 	toNotify := make(container.Set[int64], 32)
-	repoWatchers, err := repo_model.GetRepoWatchersIDs(db.DefaultContext, pr.Issue.RepoID)
+	repoWatchers, err := repo_model.GetRepoWatchersIDs(ctx, pr.Issue.RepoID)
 	if err != nil {
 		log.Error("GetRepoWatchersIDs: %v", err)
 		return
@@ -137,7 +139,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest
 	for _, id := range repoWatchers {
 		toNotify.Add(id)
 	}
-	issueParticipants, err := issues_model.GetParticipantsIDsByIssueID(pr.IssueID)
+	issueParticipants, err := issues_model.GetParticipantsIDsByIssueID(ctx, pr.IssueID)
 	if err != nil {
 		log.Error("GetParticipantsIDsByIssueID: %v", err)
 		return
@@ -158,7 +160,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest
 	}
 }
 
-func (ns *notificationService) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, c *issues_model.Comment, mentions []*user_model.User) {
+func (ns *notificationService) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, c *issues_model.Comment, mentions []*user_model.User) {
 	opts := issueNotificationOpts{
 		IssueID:              pr.Issue.ID,
 		NotificationAuthorID: r.Reviewer.ID,
@@ -180,7 +182,7 @@ func (ns *notificationService) NotifyPullRequestReview(pr *issues_model.PullRequ
 	}
 }
 
-func (ns *notificationService) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) {
+func (ns *notificationService) NotifyPullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) {
 	for _, mention := range mentions {
 		_ = ns.issueQueue.Push(issueNotificationOpts{
 			IssueID:              pr.Issue.ID,
@@ -191,7 +193,7 @@ func (ns *notificationService) NotifyPullRequestCodeComment(pr *issues_model.Pul
 	}
 }
 
-func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
+func (ns *notificationService) NotifyPullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
 	opts := issueNotificationOpts{
 		IssueID:              pr.IssueID,
 		NotificationAuthorID: doer.ID,
@@ -200,7 +202,7 @@ func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.Use
 	_ = ns.issueQueue.Push(opts)
 }
 
-func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
+func (ns *notificationService) NotifyPullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
 	opts := issueNotificationOpts{
 		IssueID:              review.IssueID,
 		NotificationAuthorID: doer.ID,
@@ -209,7 +211,7 @@ func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, r
 	_ = ns.issueQueue.Push(opts)
 }
 
-func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
+func (ns *notificationService) NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 	if !removed && doer.ID != assignee.ID {
 		opts := issueNotificationOpts{
 			IssueID:              issue.ID,
@@ -225,7 +227,7 @@ func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User,
 	}
 }
 
-func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
+func (ns *notificationService) NotifyPullReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 	if isRequest {
 		opts := issueNotificationOpts{
 			IssueID:              issue.ID,
@@ -241,8 +243,11 @@ func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, is
 	}
 }
 
-func (ns *notificationService) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) {
-	if err := activities_model.CreateRepoTransferNotification(doer, newOwner, repo); err != nil {
-		log.Error("NotifyRepoPendingTransfer: %v", err)
+func (ns *notificationService) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
+	err := db.AutoTx(ctx, func(ctx context.Context) error {
+		return activities_model.CreateRepoTransferNotification(ctx, doer, newOwner, repo)
+	})
+	if err != nil {
+		log.Error("CreateRepoTransferNotification: %v", err)
 	}
 }
diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go
index c591e1e34..37ce7661f 100644
--- a/modules/notification/webhook/webhook.go
+++ b/modules/notification/webhook/webhook.go
@@ -5,9 +5,8 @@
 package webhook
 
 import (
-	"fmt"
+	"context"
 
-	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	packages_model "code.gitea.io/gitea/models/packages"
 	"code.gitea.io/gitea/models/perm"
@@ -18,10 +17,8 @@ import (
 	"code.gitea.io/gitea/models/webhook"
 	"code.gitea.io/gitea/modules/convert"
 	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/graceful"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/notification/base"
-	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/repository"
 	"code.gitea.io/gitea/modules/setting"
 	api "code.gitea.io/gitea/modules/structs"
@@ -39,12 +36,9 @@ func NewNotifier() base.Notifier {
 	return &webhookNotifier{}
 }
 
-func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueClearLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
-	if err := issue.LoadPoster(); err != nil {
-		log.Error("loadPoster: %v", err)
+func (m *webhookNotifier) NotifyIssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
+	if err := issue.LoadPoster(ctx); err != nil {
+		log.Error("LoadPoster: %v", err)
 		return
 	}
 
@@ -53,10 +47,10 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *i
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
 	var err error
 	if issue.IsPull {
-		if err = issue.LoadPullRequest(); err != nil {
+		if err = issue.LoadPullRequest(ctx); err != nil {
 			log.Error("LoadPullRequest: %v", err)
 			return
 		}
@@ -72,7 +66,7 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *i
 		err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueLabel, &api.IssuePayload{
 			Action:     api.HookIssueLabelCleared,
 			Index:      issue.Index,
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		})
@@ -82,12 +76,12 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *i
 	}
 }
 
-func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) {
-	oldMode, _ := access_model.AccessLevel(doer, oldRepo)
-	mode, _ := access_model.AccessLevel(doer, repo)
+func (m *webhookNotifier) NotifyForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
+	oldMode, _ := access_model.AccessLevel(ctx, doer, oldRepo)
+	mode, _ := access_model.AccessLevel(ctx, doer, repo)
 
 	// forked webhook
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: oldRepo}, webhook.HookEventFork, &api.ForkPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: oldRepo}, webhook.HookEventFork, &api.ForkPayload{
 		Forkee: convert.ToRepo(oldRepo, oldMode),
 		Repo:   convert.ToRepo(repo, mode),
 		Sender: convert.ToUser(doer, nil),
@@ -95,11 +89,11 @@ func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, r
 		log.Error("PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
 	}
 
-	u := repo.MustOwner()
+	u := repo.MustOwner(ctx)
 
 	// Add to hook queue for created repo after session commit.
 	if u.IsOrganization() {
-		if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
+		if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
 			Action:       api.HookRepoCreated,
 			Repository:   convert.ToRepo(repo, perm.AccessModeOwner),
 			Organization: convert.ToUser(u, nil),
@@ -110,9 +104,9 @@ func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, r
 	}
 }
 
-func (m *webhookNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func (m *webhookNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 	// Add to hook queue for created repo after session commit.
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
 		Action:       api.HookRepoCreated,
 		Repository:   convert.ToRepo(repo, perm.AccessModeOwner),
 		Organization: convert.ToUser(u, nil),
@@ -122,22 +116,20 @@ func (m *webhookNotifier) NotifyCreateRepository(doer, u *user_model.User, repo
 	}
 }
 
-func (m *webhookNotifier) NotifyDeleteRepository(doer *user_model.User, repo *repo_model.Repository) {
-	u := repo.MustOwner()
-
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
+func (m *webhookNotifier) NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
 		Action:       api.HookRepoDeleted,
 		Repository:   convert.ToRepo(repo, perm.AccessModeOwner),
-		Organization: convert.ToUser(u, nil),
+		Organization: convert.ToUser(repo.MustOwner(ctx), nil),
 		Sender:       convert.ToUser(doer, nil),
 	}); err != nil {
 		log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err)
 	}
 }
 
-func (m *webhookNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo *repo_model.Repository) {
+func (m *webhookNotifier) NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
 	// Add to hook queue for created repo after session commit.
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{
 		Action:       api.HookRepoCreated,
 		Repository:   convert.ToRepo(repo, perm.AccessModeOwner),
 		Organization: convert.ToUser(u, nil),
@@ -147,14 +139,11 @@ func (m *webhookNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeAssignee User: %s[%d] Issue[%d] #%d in [%d] Assignee %s[%d] removed: %t", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID, assignee.Name, assignee.ID, removed))
-	defer finished()
-
+func (m *webhookNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 	if issue.IsPull {
-		mode, _ := access_model.AccessLevelUnit(doer, issue.Repo, unit.TypePullRequests)
+		mode, _ := access_model.AccessLevelUnit(ctx, doer, issue.Repo, unit.TypePullRequests)
 
-		if err := issue.LoadPullRequest(); err != nil {
+		if err := issue.LoadPullRequest(ctx); err != nil {
 			log.Error("LoadPullRequest failed: %v", err)
 			return
 		}
@@ -176,10 +165,10 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue
 			return
 		}
 	} else {
-		mode, _ := access_model.AccessLevelUnit(doer, issue.Repo, unit.TypeIssues)
+		mode, _ := access_model.AccessLevelUnit(ctx, doer, issue.Repo, unit.TypeIssues)
 		apiIssue := &api.IssuePayload{
 			Index:      issue.Index,
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		}
@@ -196,14 +185,11 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeTitle User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
+func (m *webhookNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
 	var err error
 	if issue.IsPull {
-		if err = issue.LoadPullRequest(); err != nil {
+		if err = issue.LoadPullRequest(ctx); err != nil {
 			log.Error("LoadPullRequest failed: %v", err)
 			return
 		}
@@ -229,7 +215,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *i
 					From: oldTitle,
 				},
 			},
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		})
@@ -240,14 +226,11 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *i
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeStatus User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
+func (m *webhookNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) {
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
 	var err error
 	if issue.IsPull {
-		if err = issue.LoadPullRequest(); err != nil {
+		if err = issue.LoadPullRequest(ctx); err != nil {
 			log.Error("LoadPullRequest: %v", err)
 			return
 		}
@@ -267,7 +250,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *
 	} else {
 		apiIssue := &api.IssuePayload{
 			Index:      issue.Index,
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		}
@@ -283,21 +266,21 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *
 	}
 }
 
-func (m *webhookNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) {
-	if err := issue.LoadRepo(db.DefaultContext); err != nil {
+func (m *webhookNotifier) NotifyNewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
+	if err := issue.LoadRepo(ctx); err != nil {
 		log.Error("issue.LoadRepo: %v", err)
 		return
 	}
-	if err := issue.LoadPoster(); err != nil {
+	if err := issue.LoadPoster(ctx); err != nil {
 		log.Error("issue.LoadPoster: %v", err)
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, &api.IssuePayload{
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, &api.IssuePayload{
 		Action:     api.HookIssueOpened,
 		Index:      issue.Index,
-		Issue:      convert.ToAPIIssue(issue),
+		Issue:      convert.ToAPIIssue(ctx, issue),
 		Repository: convert.ToRepo(issue.Repo, mode),
 		Sender:     convert.ToUser(issue.Poster, nil),
 	}); err != nil {
@@ -305,11 +288,8 @@ func (m *webhookNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*
 	}
 }
 
-func (m *webhookNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyNewPullRequest Pull[%d] #%d in [%d]", pull.ID, pull.Index, pull.BaseRepoID))
-	defer finished()
-
-	if err := pull.LoadIssue(); err != nil {
+func (m *webhookNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues_model.PullRequest, mentions []*user_model.User) {
+	if err := pull.LoadIssue(ctx); err != nil {
 		log.Error("pull.LoadIssue: %v", err)
 		return
 	}
@@ -317,12 +297,12 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, m
 		log.Error("pull.Issue.LoadRepo: %v", err)
 		return
 	}
-	if err := pull.Issue.LoadPoster(); err != nil {
+	if err := pull.Issue.LoadPoster(ctx); err != nil {
 		log.Error("pull.Issue.LoadPoster: %v", err)
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(pull.Issue.Poster, pull.Issue.Repo)
+	mode, _ := access_model.AccessLevel(ctx, pull.Issue.Poster, pull.Issue.Repo)
 	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pull.Issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{
 		Action:      api.HookIssueOpened,
 		Index:       pull.Issue.Index,
@@ -334,11 +314,8 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, m
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeContent User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
+func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
 	var err error
 	if issue.IsPull {
 		issue.PullRequest.Issue = issue
@@ -363,7 +340,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue
 					From: oldContent,
 				},
 			},
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		})
@@ -373,17 +350,17 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue
 	}
 }
 
-func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) {
-	if err := c.LoadPoster(); err != nil {
+func (m *webhookNotifier) NotifyUpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) {
+	if err := c.LoadPoster(ctx); err != nil {
 		log.Error("LoadPoster: %v", err)
 		return
 	}
-	if err := c.LoadIssue(); err != nil {
+	if err := c.LoadIssue(ctx); err != nil {
 		log.Error("LoadIssue: %v", err)
 		return
 	}
 
-	if err := c.Issue.LoadAttributes(db.DefaultContext); err != nil {
+	if err := c.Issue.LoadAttributes(ctx); err != nil {
 		log.Error("LoadAttributes: %v", err)
 		return
 	}
@@ -395,10 +372,10 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_m
 		eventType = webhook.HookEventIssueComment
 	}
 
-	mode, _ := access_model.AccessLevel(doer, c.Issue.Repo)
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
+	mode, _ := access_model.AccessLevel(ctx, doer, c.Issue.Repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
 		Action:  api.HookIssueCommentEdited,
-		Issue:   convert.ToAPIIssue(c.Issue),
+		Issue:   convert.ToAPIIssue(ctx, c.Issue),
 		Comment: convert.ToComment(c),
 		Changes: &api.ChangesPayload{
 			Body: &api.ChangesFromPayload{
@@ -413,7 +390,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_m
 	}
 }
 
-func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository,
+func (m *webhookNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
 ) {
 	var eventType webhook.HookEventType
@@ -423,10 +400,10 @@ func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *
 		eventType = webhook.HookEventIssueComment
 	}
 
-	mode, _ := access_model.AccessLevel(doer, repo)
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
+	mode, _ := access_model.AccessLevel(ctx, doer, repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
 		Action:     api.HookIssueCommentCreated,
-		Issue:      convert.ToAPIIssue(issue),
+		Issue:      convert.ToAPIIssue(ctx, issue),
 		Comment:    convert.ToComment(comment),
 		Repository: convert.ToRepo(repo, mode),
 		Sender:     convert.ToUser(doer, nil),
@@ -436,19 +413,19 @@ func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *
 	}
 }
 
-func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) {
+func (m *webhookNotifier) NotifyDeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) {
 	var err error
 
-	if err = comment.LoadPoster(); err != nil {
+	if err = comment.LoadPoster(ctx); err != nil {
 		log.Error("LoadPoster: %v", err)
 		return
 	}
-	if err = comment.LoadIssue(); err != nil {
+	if err = comment.LoadIssue(ctx); err != nil {
 		log.Error("LoadIssue: %v", err)
 		return
 	}
 
-	if err = comment.Issue.LoadAttributes(db.DefaultContext); err != nil {
+	if err = comment.Issue.LoadAttributes(ctx); err != nil {
 		log.Error("LoadAttributes: %v", err)
 		return
 	}
@@ -460,10 +437,10 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *is
 		eventType = webhook.HookEventIssueComment
 	}
 
-	mode, _ := access_model.AccessLevel(doer, comment.Issue.Repo)
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
+	mode, _ := access_model.AccessLevel(ctx, doer, comment.Issue.Repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
 		Action:     api.HookIssueCommentDeleted,
-		Issue:      convert.ToAPIIssue(comment.Issue),
+		Issue:      convert.ToAPIIssue(ctx, comment.Issue),
 		Comment:    convert.ToComment(comment),
 		Repository: convert.ToRepo(comment.Issue.Repo, mode),
 		Sender:     convert.ToUser(doer, nil),
@@ -473,9 +450,9 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *is
 	}
 }
 
-func (m *webhookNotifier) NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func (m *webhookNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 	// Add to hook queue for created wiki page.
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
 		Action:     api.HookWikiCreated,
 		Repository: convert.ToRepo(repo, perm.AccessModeOwner),
 		Sender:     convert.ToUser(doer, nil),
@@ -486,9 +463,9 @@ func (m *webhookNotifier) NotifyNewWikiPage(doer *user_model.User, repo *repo_mo
 	}
 }
 
-func (m *webhookNotifier) NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) {
+func (m *webhookNotifier) NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
 	// Add to hook queue for edit wiki page.
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
 		Action:     api.HookWikiEdited,
 		Repository: convert.ToRepo(repo, perm.AccessModeOwner),
 		Sender:     convert.ToUser(doer, nil),
@@ -499,9 +476,9 @@ func (m *webhookNotifier) NotifyEditWikiPage(doer *user_model.User, repo *repo_m
 	}
 }
 
-func (m *webhookNotifier) NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) {
+func (m *webhookNotifier) NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) {
 	// Add to hook queue for edit wiki page.
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{
 		Action:     api.HookWikiDeleted,
 		Repository: convert.ToRepo(repo, perm.AccessModeOwner),
 		Sender:     convert.ToUser(doer, nil),
@@ -511,12 +488,9 @@ func (m *webhookNotifier) NotifyDeleteWikiPage(doer *user_model.User, repo *repo
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue,
+func (m *webhookNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
 	addedLabels, removedLabels []*issues_model.Label,
 ) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
 	var err error
 
 	if err = issue.LoadRepo(ctx); err != nil {
@@ -524,18 +498,18 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *
 		return
 	}
 
-	if err = issue.LoadPoster(); err != nil {
+	if err = issue.LoadPoster(ctx); err != nil {
 		log.Error("LoadPoster: %v", err)
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
 	if issue.IsPull {
-		if err = issue.LoadPullRequest(); err != nil {
+		if err = issue.LoadPullRequest(ctx); err != nil {
 			log.Error("loadPullRequest: %v", err)
 			return
 		}
-		if err = issue.PullRequest.LoadIssue(); err != nil {
+		if err = issue.PullRequest.LoadIssue(ctx); err != nil {
 			log.Error("LoadIssue: %v", err)
 			return
 		}
@@ -550,7 +524,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *
 		err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueLabel, &api.IssuePayload{
 			Action:     api.HookIssueLabelUpdated,
 			Index:      issue.Index,
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		})
@@ -560,10 +534,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *
 	}
 }
 
-func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeMilestone User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID))
-	defer finished()
-
+func (m *webhookNotifier) NotifyIssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
 	var hookAction api.HookIssueAction
 	var err error
 	if issue.MilestoneID > 0 {
@@ -572,14 +543,14 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu
 		hookAction = api.HookIssueDemilestoned
 	}
 
-	if err = issue.LoadAttributes(db.DefaultContext); err != nil {
+	if err = issue.LoadAttributes(ctx); err != nil {
 		log.Error("issue.LoadAttributes failed: %v", err)
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(doer, issue.Repo)
+	mode, _ := access_model.AccessLevel(ctx, doer, issue.Repo)
 	if issue.IsPull {
-		err = issue.PullRequest.LoadIssue()
+		err = issue.PullRequest.LoadIssue(ctx)
 		if err != nil {
 			log.Error("LoadIssue: %v", err)
 			return
@@ -595,7 +566,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu
 		err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueMilestone, &api.IssuePayload{
 			Action:     hookAction,
 			Index:      issue.Index,
-			Issue:      convert.ToAPIIssue(issue),
+			Issue:      convert.ToAPIIssue(ctx, issue),
 			Repository: convert.ToRepo(issue.Repo, mode),
 			Sender:     convert.ToUser(doer, nil),
 		})
@@ -605,10 +576,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu
 	}
 }
 
-func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPushCommits User: %s[%d] in %s[%d]", pusher.Name, pusher.ID, repo.FullName(), repo.ID))
-	defer finished()
-
+func (m *webhookNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	apiPusher := convert.ToUser(pusher, nil)
 	apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL())
 	if err != nil {
@@ -632,23 +600,20 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_
 	}
 }
 
-func (m *webhookNotifier) NotifyAutoMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
+func (m *webhookNotifier) NotifyAutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	// just redirect to the NotifyMergePullRequest
-	m.NotifyMergePullRequest(pr, doer)
+	m.NotifyMergePullRequest(ctx, doer, pr)
 }
 
-func (*webhookNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyMergePullRequest Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
+func (*webhookNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
 	// Reload pull request information.
-	if err := pr.LoadAttributes(); err != nil {
+	if err := pr.LoadAttributes(ctx); err != nil {
 		log.Error("LoadAttributes: %v", err)
 		return
 	}
 
-	if err := pr.LoadIssue(); err != nil {
-		log.Error("LoadAttributes: %v", err)
+	if err := pr.LoadIssue(ctx); err != nil {
+		log.Error("LoadIssue: %v", err)
 		return
 	}
 
@@ -657,7 +622,7 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doe
 		return
 	}
 
-	mode, err := access_model.AccessLevel(doer, pr.Issue.Repo)
+	mode, err := access_model.AccessLevel(ctx, doer, pr.Issue.Repo)
 	if err != nil {
 		log.Error("models.AccessLevel: %v", err)
 		return
@@ -672,29 +637,21 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doe
 		Action:      api.HookIssueClosed,
 	}
 
-	err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pr.Issue.Repo}, webhook.HookEventPullRequest, apiPullRequest)
-	if err != nil {
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pr.Issue.Repo}, webhook.HookEventPullRequest, apiPullRequest); err != nil {
 		log.Error("PrepareWebhooks: %v", err)
 	}
 }
 
-func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestChangeTargetBranch Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
+func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
+	if err := pr.LoadIssue(ctx); err != nil {
+		log.Error("LoadIssue: %v", err)
+		return
+	}
 
 	issue := pr.Issue
-	if !issue.IsPull {
-		return
-	}
-	var err error
 
-	if err = issue.LoadPullRequest(); err != nil {
-		log.Error("LoadPullRequest failed: %v", err)
-		return
-	}
-	issue.PullRequest.Issue = issue
-	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo)
-	err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{
+	mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{
 		Action: api.HookIssueEdited,
 		Index:  issue.Index,
 		Changes: &api.ChangesPayload{
@@ -702,20 +659,15 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.U
 				From: oldBranch,
 			},
 		},
-		PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
+		PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
 		Repository:  convert.ToRepo(issue.Repo, mode),
 		Sender:      convert.ToUser(doer, nil),
-	})
-
-	if err != nil {
-		log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
+	}); err != nil {
+		log.Error("PrepareWebhooks [pr: %d]: %v", pr.ID, err)
 	}
 }
 
-func (m *webhookNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
+func (m *webhookNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
 	var reviewHookType webhook.HookEventType
 
 	switch review.Type {
@@ -731,12 +683,12 @@ func (m *webhookNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest,
 		return
 	}
 
-	if err := pr.LoadIssue(); err != nil {
-		log.Error("pr.LoadIssue: %v", err)
+	if err := pr.LoadIssue(ctx); err != nil {
+		log.Error("LoadIssue: %v", err)
 		return
 	}
 
-	mode, err := access_model.AccessLevel(review.Issue.Poster, review.Issue.Repo)
+	mode, err := access_model.AccessLevel(ctx, review.Issue.Poster, review.Issue.Repo)
 	if err != nil {
 		log.Error("models.AccessLevel: %v", err)
 		return
@@ -756,12 +708,12 @@ func (m *webhookNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest,
 	}
 }
 
-func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+func (m *webhookNotifier) NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
 	apiPusher := convert.ToUser(pusher, nil)
 	apiRepo := convert.ToRepo(repo, perm.AccessModeNone)
 	refName := git.RefEndName(refFullName)
 
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventCreate, &api.CreatePayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventCreate, &api.CreatePayload{
 		Ref:     refName,
 		Sha:     refID,
 		RefType: refType,
@@ -772,15 +724,12 @@ func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *repo_mo
 	}
 }
 
-func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestSynchronized Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID))
-	defer finished()
-
-	if err := pr.LoadIssue(); err != nil {
-		log.Error("pr.LoadIssue: %v", err)
+func (m *webhookNotifier) NotifyPullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
+	if err := pr.LoadIssue(ctx); err != nil {
+		log.Error("LoadIssue: %v", err)
 		return
 	}
-	if err := pr.Issue.LoadAttributes(db.DefaultContext); err != nil {
+	if err := pr.Issue.LoadAttributes(ctx); err != nil {
 		log.Error("LoadAttributes: %v", err)
 		return
 	}
@@ -796,12 +745,12 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p
 	}
 }
 
-func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+func (m *webhookNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
 	apiPusher := convert.ToUser(pusher, nil)
 	apiRepo := convert.ToRepo(repo, perm.AccessModeNone)
 	refName := git.RefEndName(refFullName)
 
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: repo}, webhook.HookEventDelete, &api.DeletePayload{
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventDelete, &api.DeletePayload{
 		Ref:        refName,
 		RefType:    refType,
 		PusherType: api.PusherTypeUser,
@@ -812,14 +761,14 @@ func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *repo_mo
 	}
 }
 
-func sendReleaseHook(doer *user_model.User, rel *repo_model.Release, action api.HookReleaseAction) {
-	if err := rel.LoadAttributes(); err != nil {
+func sendReleaseHook(ctx context.Context, doer *user_model.User, rel *repo_model.Release, action api.HookReleaseAction) {
+	if err := rel.LoadAttributes(ctx); err != nil {
 		log.Error("LoadAttributes: %v", err)
 		return
 	}
 
-	mode, _ := access_model.AccessLevel(doer, rel.Repo)
-	if err := webhook_services.PrepareWebhooks(db.DefaultContext, webhook_services.EventSource{Repository: rel.Repo}, webhook.HookEventRelease, &api.ReleasePayload{
+	mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo)
+	if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: rel.Repo}, webhook.HookEventRelease, &api.ReleasePayload{
 		Action:     action,
 		Release:    convert.ToRelease(rel),
 		Repository: convert.ToRepo(rel.Repo, mode),
@@ -829,22 +778,19 @@ func sendReleaseHook(doer *user_model.User, rel *repo_model.Release, action api.
 	}
 }
 
-func (m *webhookNotifier) NotifyNewRelease(rel *repo_model.Release) {
-	sendReleaseHook(rel.Publisher, rel, api.HookReleasePublished)
+func (m *webhookNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
+	sendReleaseHook(ctx, rel.Publisher, rel, api.HookReleasePublished)
 }
 
-func (m *webhookNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) {
-	sendReleaseHook(doer, rel, api.HookReleaseUpdated)
+func (m *webhookNotifier) NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
+	sendReleaseHook(ctx, doer, rel, api.HookReleaseUpdated)
 }
 
-func (m *webhookNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) {
-	sendReleaseHook(doer, rel, api.HookReleaseDeleted)
+func (m *webhookNotifier) NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
+	sendReleaseHook(ctx, doer, rel, api.HookReleaseDeleted)
 }
 
-func (m *webhookNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifySyncPushCommits User: %s[%d] in %s[%d]", pusher.Name, pusher.ID, repo.FullName(), repo.ID))
-	defer finished()
-
+func (m *webhookNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
 	apiPusher := convert.ToUser(pusher, nil)
 	apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL())
 	if err != nil {
@@ -868,31 +814,28 @@ func (m *webhookNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *r
 	}
 }
 
-func (m *webhookNotifier) NotifySyncCreateRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
-	m.NotifyCreateRef(pusher, repo, refType, refFullName, refID)
+func (m *webhookNotifier) NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) {
+	m.NotifyCreateRef(ctx, pusher, repo, refType, refFullName, refID)
 }
 
-func (m *webhookNotifier) NotifySyncDeleteRef(pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
-	m.NotifyDeleteRef(pusher, repo, refType, refFullName)
+func (m *webhookNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) {
+	m.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName)
 }
 
-func (m *webhookNotifier) NotifyPackageCreate(doer *user_model.User, pd *packages_model.PackageDescriptor) {
-	notifyPackage(doer, pd, api.HookPackageCreated)
+func (m *webhookNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
+	notifyPackage(ctx, doer, pd, api.HookPackageCreated)
 }
 
-func (m *webhookNotifier) NotifyPackageDelete(doer *user_model.User, pd *packages_model.PackageDescriptor) {
-	notifyPackage(doer, pd, api.HookPackageDeleted)
+func (m *webhookNotifier) NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
+	notifyPackage(ctx, doer, pd, api.HookPackageDeleted)
 }
 
-func notifyPackage(sender *user_model.User, pd *packages_model.PackageDescriptor, action api.HookPackageAction) {
+func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_model.PackageDescriptor, action api.HookPackageAction) {
 	source := webhook_services.EventSource{
 		Repository: pd.Repository,
 		Owner:      pd.Owner,
 	}
 
-	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.notifyPackage Package: %s[%d]", pd.Package.Name, pd.Package.ID))
-	defer finished()
-
 	apiPackage, err := convert.ToPackage(ctx, pd, sender)
 	if err != nil {
 		log.Error("Error converting package: %v", err)
diff --git a/modules/repository/repo.go b/modules/repository/repo.go
index 1d3a4658c..f1360f447 100644
--- a/modules/repository/repo.go
+++ b/modules/repository/repo.go
@@ -288,7 +288,7 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository)
 	}
 	for page := 1; ; page++ {
 		opts.Page = page
-		rels, err := repo_model.GetReleasesByRepoID(repo.ID, opts)
+		rels, err := repo_model.GetReleasesByRepoID(gitRepo.Ctx, repo.ID, opts)
 		if err != nil {
 			return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
 		}
diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go
index b69a67410..188cfce28 100644
--- a/routers/api/packages/conan/conan.go
+++ b/routers/api/packages/conan/conan.go
@@ -676,7 +676,7 @@ func deleteRecipeOrPackage(apictx *context.Context, rref *conan_module.RecipeRef
 	}
 
 	if versionDeleted {
-		notification.NotifyPackageDelete(apictx.Doer, pd)
+		notification.NotifyPackageDelete(apictx, apictx.Doer, pd)
 	}
 
 	return nil
diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go
index bd629b87c..a4ba44035 100644
--- a/routers/api/v1/misc/nodeinfo.go
+++ b/routers/api/v1/misc/nodeinfo.go
@@ -42,7 +42,7 @@ func NodeInfo(ctx *context.APIContext) {
 			usersActiveMonth := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo}))
 			usersActiveHalfyear := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo}))
 
-			allIssues, _ := issues_model.CountIssues(&issues_model.IssuesOptions{})
+			allIssues, _ := issues_model.CountIssues(ctx, &issues_model.IssuesOptions{})
 			allComments, _ := issues_model.CountComments(&issues_model.FindCommentsOptions{})
 
 			nodeInfoUsage = structs.NodeInfoUsage{
diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go
index f8e1fb086..6d9664400 100644
--- a/routers/api/v1/notify/repo.go
+++ b/routers/api/v1/notify/repo.go
@@ -109,7 +109,7 @@ func ListRepoNotifications(ctx *context.APIContext) {
 	}
 	opts.RepoID = ctx.Repo.Repository.ID
 
-	totalCount, err := activities_model.CountNotifications(opts)
+	totalCount, err := activities_model.CountNotifications(ctx, opts)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
@@ -120,7 +120,7 @@ func ListRepoNotifications(ctx *context.APIContext) {
 		ctx.InternalServerError(err)
 		return
 	}
-	err = nl.LoadAttributes()
+	err = nl.LoadAttributes(ctx)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
@@ -217,12 +217,12 @@ func ReadRepoNotifications(ctx *context.APIContext) {
 	changed := make([]*structs.NotificationThread, 0, len(nl))
 
 	for _, n := range nl {
-		notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus)
+		notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus)
 		if err != nil {
 			ctx.InternalServerError(err)
 			return
 		}
-		_ = notif.LoadAttributes()
+		_ = notif.LoadAttributes(ctx)
 		changed = append(changed, convert.ToNotificationThread(notif))
 	}
 	ctx.JSON(http.StatusResetContent, changed)
diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go
index 44a1d30a5..f8e496091 100644
--- a/routers/api/v1/notify/threads.go
+++ b/routers/api/v1/notify/threads.go
@@ -42,7 +42,7 @@ func GetThread(ctx *context.APIContext) {
 	if n == nil {
 		return
 	}
-	if err := n.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) {
+	if err := n.LoadAttributes(ctx); err != nil && !issues_model.IsErrCommentNotExist(err) {
 		ctx.InternalServerError(err)
 		return
 	}
@@ -89,12 +89,12 @@ func ReadThread(ctx *context.APIContext) {
 		targetStatus = activities_model.NotificationStatusRead
 	}
 
-	notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus)
+	notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
-	if err = notif.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) {
+	if err = notif.LoadAttributes(ctx); err != nil && !issues_model.IsErrCommentNotExist(err) {
 		ctx.InternalServerError(err)
 		return
 	}
@@ -102,7 +102,7 @@ func ReadThread(ctx *context.APIContext) {
 }
 
 func getThread(ctx *context.APIContext) *activities_model.Notification {
-	n, err := activities_model.GetNotificationByID(ctx.ParamsInt64(":id"))
+	n, err := activities_model.GetNotificationByID(ctx, ctx.ParamsInt64(":id"))
 	if err != nil {
 		if db.IsErrNotExist(err) {
 			ctx.Error(http.StatusNotFound, "GetNotificationByID", err)
diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go
index 1b6706e16..5f4d8b35c 100644
--- a/routers/api/v1/notify/user.go
+++ b/routers/api/v1/notify/user.go
@@ -69,7 +69,7 @@ func ListNotifications(ctx *context.APIContext) {
 		return
 	}
 
-	totalCount, err := activities_model.CountNotifications(opts)
+	totalCount, err := activities_model.CountNotifications(ctx, opts)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
@@ -80,7 +80,7 @@ func ListNotifications(ctx *context.APIContext) {
 		ctx.InternalServerError(err)
 		return
 	}
-	err = nl.LoadAttributes()
+	err = nl.LoadAttributes(ctx)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
@@ -162,12 +162,12 @@ func ReadNotifications(ctx *context.APIContext) {
 	changed := make([]*structs.NotificationThread, 0, len(nl))
 
 	for _, n := range nl {
-		notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus)
+		notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus)
 		if err != nil {
 			ctx.InternalServerError(err)
 			return
 		}
-		_ = notif.LoadAttributes()
+		_ = notif.LoadAttributes(ctx)
 		changed = append(changed, convert.ToNotificationThread(notif))
 	}
 
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index f3e7834a4..b2bcc4d58 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -542,7 +542,7 @@ func GetTeamRepos(ctx *context.APIContext) {
 	}
 	repos := make([]*api.Repository, len(teamRepos))
 	for i, repo := range teamRepos {
-		access, err := access_model.AccessLevel(ctx.Doer, repo)
+		access, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
 			return
@@ -593,7 +593,7 @@ func GetTeamRepo(ctx *context.APIContext) {
 		return
 	}
 
-	access, err := access_model.AccessLevel(ctx.Doer, repo)
+	access, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
 		return
@@ -650,7 +650,7 @@ func AddTeamRepository(ctx *context.APIContext) {
 	if ctx.Written() {
 		return
 	}
-	if access, err := access_model.AccessLevel(ctx.Doer, repo); err != nil {
+	if access, err := access_model.AccessLevel(ctx, ctx.Doer, repo); err != nil {
 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
 		return
 	} else if access < perm.AccessModeAdmin {
@@ -700,7 +700,7 @@ func RemoveTeamRepository(ctx *context.APIContext) {
 	if ctx.Written() {
 		return
 	}
-	if access, err := access_model.AccessLevel(ctx.Doer, repo); err != nil {
+	if access, err := access_model.AccessLevel(ctx, ctx.Doer, repo); err != nil {
 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
 		return
 	} else if access < perm.AccessModeAdmin {
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index 84a172e92..d10a308df 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -427,7 +427,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
 		requiredApprovals = form.RequiredApprovals
 	}
 
-	whitelistUsers, err := user_model.GetUserIDsByNames(form.PushWhitelistUsernames, false)
+	whitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false)
 	if err != nil {
 		if user_model.IsErrUserNotExist(err) {
 			ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
@@ -436,7 +436,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
 		return
 	}
-	mergeWhitelistUsers, err := user_model.GetUserIDsByNames(form.MergeWhitelistUsernames, false)
+	mergeWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false)
 	if err != nil {
 		if user_model.IsErrUserNotExist(err) {
 			ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
@@ -445,7 +445,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
 		return
 	}
-	approvalsWhitelistUsers, err := user_model.GetUserIDsByNames(form.ApprovalsWhitelistUsernames, false)
+	approvalsWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false)
 	if err != nil {
 		if user_model.IsErrUserNotExist(err) {
 			ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
@@ -656,7 +656,7 @@ func EditBranchProtection(ctx *context.APIContext) {
 
 	var whitelistUsers []int64
 	if form.PushWhitelistUsernames != nil {
-		whitelistUsers, err = user_model.GetUserIDsByNames(form.PushWhitelistUsernames, false)
+		whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false)
 		if err != nil {
 			if user_model.IsErrUserNotExist(err) {
 				ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
@@ -670,7 +670,7 @@ func EditBranchProtection(ctx *context.APIContext) {
 	}
 	var mergeWhitelistUsers []int64
 	if form.MergeWhitelistUsernames != nil {
-		mergeWhitelistUsers, err = user_model.GetUserIDsByNames(form.MergeWhitelistUsernames, false)
+		mergeWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false)
 		if err != nil {
 			if user_model.IsErrUserNotExist(err) {
 				ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
@@ -684,7 +684,7 @@ func EditBranchProtection(ctx *context.APIContext) {
 	}
 	var approvalsWhitelistUsers []int64
 	if form.ApprovalsWhitelistUsernames != nil {
-		approvalsWhitelistUsers, err = user_model.GetUserIDsByNames(form.ApprovalsWhitelistUsernames, false)
+		approvalsWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false)
 		if err != nil {
 			if user_model.IsErrUserNotExist(err) {
 				ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go
index 112a9562f..c0a79d1a6 100644
--- a/routers/api/v1/repo/fork.go
+++ b/routers/api/v1/repo/fork.go
@@ -59,7 +59,7 @@ func ListForks(ctx *context.APIContext) {
 	}
 	apiForks := make([]*api.Repository, len(forks))
 	for i, fork := range forks {
-		access, err := access_model.AccessLevel(ctx.Doer, fork)
+		access, err := access_model.AccessLevel(ctx, ctx.Doer, fork)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
 			return
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 08e3e0374..60f9859e1 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -179,7 +179,7 @@ func SearchIssues(ctx *context.APIContext) {
 	repoCond := repo_model.SearchRepositoryCondition(opts)
 	repoIDs, _, err := repo_model.SearchRepositoryIDs(opts)
 	if err != nil {
-		ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
+		ctx.Error(http.StatusInternalServerError, "SearchRepositoryIDs", err)
 		return
 	}
 
@@ -268,7 +268,7 @@ func SearchIssues(ctx *context.APIContext) {
 			issuesOpt.ReviewRequestedID = ctxUserID
 		}
 
-		if issues, err = issues_model.Issues(issuesOpt); err != nil {
+		if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "Issues", err)
 			return
 		}
@@ -276,7 +276,7 @@ func SearchIssues(ctx *context.APIContext) {
 		issuesOpt.ListOptions = db.ListOptions{
 			Page: -1,
 		}
-		if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil {
+		if filteredCount, err = issues_model.CountIssues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "CountIssues", err)
 			return
 		}
@@ -284,7 +284,7 @@ func SearchIssues(ctx *context.APIContext) {
 
 	ctx.SetLinkHeader(int(filteredCount), limit)
 	ctx.SetTotalCountHeader(filteredCount)
-	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
 }
 
 // ListIssues list the issues of a repository
@@ -477,7 +477,7 @@ func ListIssues(ctx *context.APIContext) {
 			MentionedID:       mentionedByID,
 		}
 
-		if issues, err = issues_model.Issues(issuesOpt); err != nil {
+		if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "Issues", err)
 			return
 		}
@@ -485,7 +485,7 @@ func ListIssues(ctx *context.APIContext) {
 		issuesOpt.ListOptions = db.ListOptions{
 			Page: -1,
 		}
-		if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil {
+		if filteredCount, err = issues_model.CountIssues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "CountIssues", err)
 			return
 		}
@@ -493,7 +493,7 @@ func ListIssues(ctx *context.APIContext) {
 
 	ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize)
 	ctx.SetTotalCountHeader(filteredCount)
-	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
 }
 
 func getUserIDForFilter(ctx *context.APIContext, queryName string) int64 {
@@ -555,7 +555,7 @@ func GetIssue(ctx *context.APIContext) {
 		}
 		return
 	}
-	ctx.JSON(http.StatusOK, convert.ToAPIIssue(issue))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
 }
 
 // CreateIssue create an issue of a repository
@@ -612,7 +612,7 @@ func CreateIssue(ctx *context.APIContext) {
 	var err error
 	if ctx.Repo.CanWrite(unit.TypeIssues) {
 		issue.MilestoneID = form.Milestone
-		assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
+		assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees)
 		if err != nil {
 			if user_model.IsErrUserNotExist(err) {
 				ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
@@ -671,7 +671,7 @@ func CreateIssue(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "GetIssueByID", err)
 		return
 	}
-	ctx.JSON(http.StatusCreated, convert.ToAPIIssue(issue))
+	ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
 }
 
 // EditIssue modify an issue of a repository
@@ -823,11 +823,11 @@ func EditIssue(ctx *context.APIContext) {
 	}
 
 	if titleChanged {
-		notification.NotifyIssueChangeTitle(ctx.Doer, issue, oldTitle)
+		notification.NotifyIssueChangeTitle(ctx, ctx.Doer, issue, oldTitle)
 	}
 
 	if statusChangeComment != nil {
-		notification.NotifyIssueChangeStatus(ctx.Doer, issue, statusChangeComment, issue.IsClosed)
+		notification.NotifyIssueChangeStatus(ctx, ctx.Doer, issue, statusChangeComment, issue.IsClosed)
 	}
 
 	// Refetch from database to assign some automatic values
@@ -836,11 +836,11 @@ func EditIssue(ctx *context.APIContext) {
 		ctx.InternalServerError(err)
 		return
 	}
-	if err = issue.LoadMilestone(); err != nil {
+	if err = issue.LoadMilestone(ctx); err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
-	ctx.JSON(http.StatusCreated, convert.ToAPIIssue(issue))
+	ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
 }
 
 func DeleteIssue(ctx *context.APIContext) {
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index 89038e4f1..a5da09172 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -91,7 +91,7 @@ func ListIssueComments(ctx *context.APIContext) {
 		return
 	}
 
-	if err := issues_model.CommentList(comments).LoadPosters(); err != nil {
+	if err := issues_model.CommentList(comments).LoadPosters(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadPosters", err)
 		return
 	}
@@ -178,7 +178,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
 		return
 	}
 
-	if err := issues_model.CommentList(comments).LoadPosters(); err != nil {
+	if err := issues_model.CommentList(comments).LoadPosters(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadPosters", err)
 		return
 	}
@@ -187,7 +187,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
 	for _, comment := range comments {
 		if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) {
 			comment.Issue = issue
-			apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.Doer))
+			apiComments = append(apiComments, convert.ToTimelineComment(ctx, comment, ctx.Doer))
 		}
 	}
 
@@ -281,21 +281,21 @@ func ListRepoIssueComments(ctx *context.APIContext) {
 		return
 	}
 
-	if err = issues_model.CommentList(comments).LoadPosters(); err != nil {
+	if err = issues_model.CommentList(comments).LoadPosters(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadPosters", err)
 		return
 	}
 
 	apiComments := make([]*api.Comment, len(comments))
-	if err := issues_model.CommentList(comments).LoadIssues(); err != nil {
+	if err := issues_model.CommentList(comments).LoadIssues(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssues", err)
 		return
 	}
-	if err := issues_model.CommentList(comments).LoadPosters(); err != nil {
+	if err := issues_model.CommentList(comments).LoadPosters(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadPosters", err)
 		return
 	}
-	if _, err := issues_model.CommentList(comments).Issues().LoadRepositories(); err != nil {
+	if _, err := issues_model.CommentList(comments).Issues().LoadRepositories(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadRepositories", err)
 		return
 	}
@@ -354,7 +354,7 @@ func CreateIssueComment(ctx *context.APIContext) {
 		return
 	}
 
-	comment, err := comment_service.CreateIssueComment(ctx.Doer, ctx.Repo.Repository, issue, form.Body, nil)
+	comment, err := comment_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Body, nil)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "CreateIssueComment", err)
 		return
@@ -409,7 +409,7 @@ func GetIssueComment(ctx *context.APIContext) {
 		return
 	}
 
-	if err = comment.LoadIssue(); err != nil {
+	if err = comment.LoadIssue(ctx); err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
@@ -423,7 +423,7 @@ func GetIssueComment(ctx *context.APIContext) {
 		return
 	}
 
-	if err := comment.LoadPoster(); err != nil {
+	if err := comment.LoadPoster(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "comment.LoadPoster", err)
 		return
 	}
@@ -548,7 +548,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
 
 	oldContent := comment.Content
 	comment.Content = form.Body
-	if err := comment_service.UpdateComment(comment, ctx.Doer, oldContent); err != nil {
+	if err := comment_service.UpdateComment(ctx, comment, ctx.Doer, oldContent); err != nil {
 		ctx.Error(http.StatusInternalServerError, "UpdateComment", err)
 		return
 	}
@@ -647,7 +647,7 @@ func deleteIssueComment(ctx *context.APIContext) {
 		return
 	}
 
-	if err = comment_service.DeleteComment(ctx.Doer, comment); err != nil {
+	if err = comment_service.DeleteComment(ctx, ctx.Doer, comment); err != nil {
 		ctx.Error(http.StatusInternalServerError, "DeleteCommentByID", err)
 		return
 	}
diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go
index f4c40d2bc..fb7fd713b 100644
--- a/routers/api/v1/repo/issue_reaction.go
+++ b/routers/api/v1/repo/issue_reaction.go
@@ -58,7 +58,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
 		return
 	}
 
-	if err := comment.LoadIssue(); err != nil {
+	if err := comment.LoadIssue(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err)
 	}
 
@@ -185,7 +185,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
 		return
 	}
 
-	err = comment.LoadIssue()
+	err = comment.LoadIssue(ctx)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err)
 	}
diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go
index 1e26403ec..e3abb973b 100644
--- a/routers/api/v1/repo/issue_tracked_time.go
+++ b/routers/api/v1/repo/issue_tracked_time.go
@@ -139,7 +139,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
 	}
 
 	ctx.SetTotalCountHeader(count)
-	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
+	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
 }
 
 // AddTime add time manual to the given issue
@@ -224,7 +224,7 @@ func AddTime(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
-	ctx.JSON(http.StatusOK, convert.ToTrackedTime(trackedTime))
+	ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, trackedTime))
 }
 
 // ResetIssueTime reset time manual to the given issue
@@ -448,7 +448,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
-	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
+	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
 }
 
 // ListTrackedTimesByRepository lists all tracked times of the repository
@@ -558,7 +558,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
 	}
 
 	ctx.SetTotalCountHeader(count)
-	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
+	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
 }
 
 // ListMyTrackedTimes lists all tracked times of the current user
@@ -620,5 +620,5 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
 	}
 
 	ctx.SetTotalCountHeader(count)
-	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes))
+	ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
 }
diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go
index ed371d787..aeef862b1 100644
--- a/routers/api/v1/repo/migrate.go
+++ b/routers/api/v1/repo/migrate.go
@@ -195,7 +195,7 @@ func Migrate(ctx *context.APIContext) {
 		}
 
 		if err == nil {
-			notification.NotifyMigrateRepository(ctx.Doer, repoOwner, repo)
+			notification.NotifyMigrateRepository(ctx, ctx.Doer, repoOwner, repo)
 			return
 		}
 
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index f7e82dab3..fba7ed646 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -109,19 +109,19 @@ func ListPullRequests(ctx *context.APIContext) {
 
 	apiPrs := make([]*api.PullRequest, len(prs))
 	for i := range prs {
-		if err = prs[i].LoadIssue(); err != nil {
+		if err = prs[i].LoadIssue(ctx); err != nil {
 			ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 			return
 		}
-		if err = prs[i].LoadAttributes(); err != nil {
+		if err = prs[i].LoadAttributes(ctx); err != nil {
 			ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 			return
 		}
-		if err = prs[i].LoadBaseRepoCtx(ctx); err != nil {
+		if err = prs[i].LoadBaseRepo(ctx); err != nil {
 			ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err)
 			return
 		}
-		if err = prs[i].LoadHeadRepoCtx(ctx); err != nil {
+		if err = prs[i].LoadHeadRepo(ctx); err != nil {
 			ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err)
 			return
 		}
@@ -173,11 +173,11 @@ func GetPullRequest(ctx *context.APIContext) {
 		return
 	}
 
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err)
 		return
 	}
-	if err = pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err = pr.LoadHeadRepo(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err)
 		return
 	}
@@ -300,7 +300,7 @@ func CreatePullRequest(ctx *context.APIContext) {
 	defer headGitRepo.Close()
 
 	// Check if another PR exists with the same targets
-	existingPr, err := issues_model.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, issues_model.PullRequestFlowGithub)
+	existingPr, err := issues_model.GetUnmergedPullRequest(ctx, headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, issues_model.PullRequestFlowGithub)
 	if err != nil {
 		if !issues_model.IsErrPullRequestNotExist(err) {
 			ctx.Error(http.StatusInternalServerError, "GetUnmergedPullRequest", err)
@@ -320,7 +320,7 @@ func CreatePullRequest(ctx *context.APIContext) {
 	}
 
 	if len(form.Labels) > 0 {
-		labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
+		labels, err := issues_model.GetLabelsInRepoByIDs(ctx, ctx.Repo.Repository.ID, form.Labels)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err)
 			return
@@ -334,7 +334,7 @@ func CreatePullRequest(ctx *context.APIContext) {
 		}
 
 		if ctx.Repo.Owner.IsOrganization() {
-			orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels)
+			orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx, ctx.Repo.Owner.ID, form.Labels)
 			if err != nil {
 				ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err)
 				return
@@ -389,7 +389,7 @@ func CreatePullRequest(ctx *context.APIContext) {
 	}
 
 	// Get all assignee IDs
-	assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
+	assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees)
 	if err != nil {
 		if user_model.IsErrUserNotExist(err) {
 			ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
@@ -400,7 +400,7 @@ func CreatePullRequest(ctx *context.APIContext) {
 	}
 	// Check if the passed assignees is assignable
 	for _, aID := range assigneeIDs {
-		assignee, err := user_model.GetUserByID(aID)
+		assignee, err := user_model.GetUserByIDCtx(ctx, aID)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "GetUserByID", err)
 			return
@@ -483,7 +483,7 @@ func EditPullRequest(ctx *context.APIContext) {
 		return
 	}
 
-	err = pr.LoadIssue()
+	err = pr.LoadIssue(ctx)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 		return
@@ -551,14 +551,14 @@ func EditPullRequest(ctx *context.APIContext) {
 	}
 
 	if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Labels != nil {
-		labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
+		labels, err := issues_model.GetLabelsInRepoByIDs(ctx, ctx.Repo.Repository.ID, form.Labels)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err)
 			return
 		}
 
 		if ctx.Repo.Owner.IsOrganization() {
-			orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels)
+			orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx, ctx.Repo.Owner.ID, form.Labels)
 			if err != nil {
 				ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err)
 				return
@@ -591,11 +591,11 @@ func EditPullRequest(ctx *context.APIContext) {
 	}
 
 	if titleChanged {
-		notification.NotifyIssueChangeTitle(ctx.Doer, issue, oldTitle)
+		notification.NotifyIssueChangeTitle(ctx, ctx.Doer, issue, oldTitle)
 	}
 
 	if statusChangeComment != nil {
-		notification.NotifyIssueChangeStatus(ctx.Doer, issue, statusChangeComment, issue.IsClosed)
+		notification.NotifyIssueChangeStatus(ctx, ctx.Doer, issue, statusChangeComment, issue.IsClosed)
 	}
 
 	// change pull target branch
@@ -619,7 +619,7 @@ func EditPullRequest(ctx *context.APIContext) {
 			}
 			return
 		}
-		notification.NotifyPullRequestChangeTargetBranch(ctx.Doer, pr, form.Base)
+		notification.NotifyPullRequestChangeTargetBranch(ctx, ctx.Doer, pr, form.Base)
 	}
 
 	// update allow edits
@@ -743,12 +743,12 @@ func MergePullRequest(ctx *context.APIContext) {
 		return
 	}
 
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err)
 		return
 	}
 
-	if err := pr.LoadIssueCtx(ctx); err != nil {
+	if err := pr.LoadIssue(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 		return
 	}
@@ -811,7 +811,7 @@ func MergePullRequest(ctx *context.APIContext) {
 
 	message := strings.TrimSpace(form.MergeTitleField)
 	if len(message) == 0 {
-		message, err = pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do))
+		message, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do))
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "GetDefaultMergeMessage", err)
 			return
@@ -1097,7 +1097,7 @@ func UpdatePullRequest(ctx *context.APIContext) {
 		return
 	}
 
-	if err = pr.LoadIssue(); err != nil {
+	if err = pr.LoadIssue(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 		return
 	}
@@ -1107,11 +1107,11 @@ func UpdatePullRequest(ctx *context.APIContext) {
 		return
 	}
 
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err)
 		return
 	}
-	if err = pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err = pr.LoadHeadRepo(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err)
 		return
 	}
@@ -1267,7 +1267,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
 		return
 	}
 
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
@@ -1383,12 +1383,12 @@ func GetPullRequestFiles(ctx *context.APIContext) {
 		return
 	}
 
-	if err := pr.LoadBaseRepo(); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
 
-	if err := pr.LoadHeadRepo(); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go
index f36d0586a..df88e2a57 100644
--- a/routers/api/v1/repo/pull_review.go
+++ b/routers/api/v1/repo/pull_review.go
@@ -71,7 +71,7 @@ func ListPullReviews(ctx *context.APIContext) {
 		return
 	}
 
-	if err = pr.LoadIssue(); err != nil {
+	if err = pr.LoadIssue(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 		return
 	}
@@ -476,7 +476,7 @@ func SubmitPullReview(ctx *context.APIContext) {
 
 // preparePullReviewType return ReviewType and false or nil and true if an error happen
 func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest, event api.ReviewStateType, body string, hasComments bool) (issues_model.ReviewType, bool) {
-	if err := pr.LoadIssue(); err != nil {
+	if err := pr.LoadIssue(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
 		return -1, true
 	}
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index acc9696e1..60cc19d56 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -61,7 +61,7 @@ func GetRelease(ctx *context.APIContext) {
 		return
 	}
 
-	if err := release.LoadAttributes(); err != nil {
+	if err := release.LoadAttributes(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
@@ -123,14 +123,14 @@ func ListReleases(ctx *context.APIContext) {
 		IsPreRelease:  ctx.FormOptionalBool("pre-release"),
 	}
 
-	releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts)
+	releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err)
 		return
 	}
 	rels := make([]*api.Release, len(releases))
 	for i, release := range releases {
-		if err := release.LoadAttributes(); err != nil {
+		if err := release.LoadAttributes(ctx); err != nil {
 			ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 			return
 		}
@@ -313,7 +313,7 @@ func EditRelease(ctx *context.APIContext) {
 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
 		return
 	}
-	if err := rel.LoadAttributes(); err != nil {
+	if err := rel.LoadAttributes(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go
index a469877c1..02f85d384 100644
--- a/routers/api/v1/repo/release_attachment.go
+++ b/routers/api/v1/repo/release_attachment.go
@@ -114,7 +114,7 @@ func ListReleaseAttachments(ctx *context.APIContext) {
 		ctx.NotFound()
 		return
 	}
-	if err := release.LoadAttributes(); err != nil {
+	if err := release.LoadAttributes(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go
index 2cb97c58a..77395bb46 100644
--- a/routers/api/v1/repo/release_tags.go
+++ b/routers/api/v1/repo/release_tags.go
@@ -60,7 +60,7 @@ func GetReleaseByTag(ctx *context.APIContext) {
 		return
 	}
 
-	if err = release.LoadAttributes(); err != nil {
+	if err = release.LoadAttributes(ctx); err != nil {
 		ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
 		return
 	}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index de8a4d186..29febe751 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -191,7 +191,7 @@ func Search(ctx *context.APIContext) {
 	}
 
 	var err error
-	repos, count, err := repo_model.SearchRepository(opts)
+	repos, count, err := repo_model.SearchRepository(ctx, opts)
 	if err != nil {
 		ctx.JSON(http.StatusInternalServerError, api.SearchError{
 			OK:    false,
@@ -209,7 +209,7 @@ func Search(ctx *context.APIContext) {
 			})
 			return
 		}
-		accessMode, err := access_model.AccessLevel(ctx.Doer, repo)
+		accessMode, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
 		if err != nil {
 			ctx.JSON(http.StatusInternalServerError, api.SearchError{
 				OK:    false,
diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go
index 6d9564854..734a550a7 100644
--- a/routers/api/v1/repo/wiki.go
+++ b/routers/api/v1/repo/wiki.go
@@ -86,7 +86,7 @@ func NewWikiPage(ctx *context.APIContext) {
 	wikiPage := getWikiPage(ctx, wikiName)
 
 	if !ctx.Written() {
-		notification.NotifyNewWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName, form.Message)
+		notification.NotifyNewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.Message)
 		ctx.JSON(http.StatusCreated, wikiPage)
 	}
 }
@@ -154,7 +154,7 @@ func EditWikiPage(ctx *context.APIContext) {
 	wikiPage := getWikiPage(ctx, newWikiName)
 
 	if !ctx.Written() {
-		notification.NotifyEditWikiPage(ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message)
+		notification.NotifyEditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message)
 		ctx.JSON(http.StatusOK, wikiPage)
 	}
 }
@@ -245,7 +245,7 @@ func DeleteWikiPage(ctx *context.APIContext) {
 		return
 	}
 
-	notification.NotifyDeleteWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName)
+	notification.NotifyDeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName)
 
 	ctx.Status(http.StatusNoContent)
 }
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 709e3a6c5..d1917a993 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -39,7 +39,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
 
 	apiRepos := make([]*api.Repository, 0, len(repos))
 	for i := range repos {
-		access, err := access_model.AccessLevel(ctx.Doer, repos[i])
+		access, err := access_model.AccessLevel(ctx, ctx.Doer, repos[i])
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
 			return
@@ -112,7 +112,7 @@ func ListMyRepos(ctx *context.APIContext) {
 	}
 
 	var err error
-	repos, count, err := repo_model.SearchRepository(opts)
+	repos, count, err := repo_model.SearchRepository(ctx, opts)
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "SearchRepository", err)
 		return
@@ -124,7 +124,7 @@ func ListMyRepos(ctx *context.APIContext) {
 			ctx.Error(http.StatusInternalServerError, "GetOwner", err)
 			return
 		}
-		accessMode, err := access_model.AccessLevel(ctx.Doer, repo)
+		accessMode, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
 		if err != nil {
 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
 		}
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index 9cb9ec79b..96748c630 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -6,6 +6,7 @@
 package user
 
 import (
+	std_context "context"
 	"net/http"
 
 	"code.gitea.io/gitea/models/db"
@@ -20,15 +21,15 @@ import (
 
 // getStarredRepos returns the repos that the user with the specified userID has
 // starred
-func getStarredRepos(user *user_model.User, private bool, listOptions db.ListOptions) ([]*api.Repository, error) {
-	starredRepos, err := repo_model.GetStarredRepos(user.ID, private, listOptions)
+func getStarredRepos(ctx std_context.Context, user *user_model.User, private bool, listOptions db.ListOptions) ([]*api.Repository, error) {
+	starredRepos, err := repo_model.GetStarredRepos(ctx, user.ID, private, listOptions)
 	if err != nil {
 		return nil, err
 	}
 
 	repos := make([]*api.Repository, len(starredRepos))
 	for i, starred := range starredRepos {
-		access, err := access_model.AccessLevel(user, starred)
+		access, err := access_model.AccessLevel(ctx, user, starred)
 		if err != nil {
 			return nil, err
 		}
@@ -63,7 +64,7 @@ func GetStarredRepos(ctx *context.APIContext) {
 	//     "$ref": "#/responses/RepositoryList"
 
 	private := ctx.ContextUser.ID == ctx.Doer.ID
-	repos, err := getStarredRepos(ctx.ContextUser, private, utils.GetListOptions(ctx))
+	repos, err := getStarredRepos(ctx, ctx.ContextUser, private, utils.GetListOptions(ctx))
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "getStarredRepos", err)
 		return
@@ -93,7 +94,7 @@ func GetMyStarredRepos(ctx *context.APIContext) {
 	//   "200":
 	//     "$ref": "#/responses/RepositoryList"
 
-	repos, err := getStarredRepos(ctx.Doer, true, utils.GetListOptions(ctx))
+	repos, err := getStarredRepos(ctx, ctx.Doer, true, utils.GetListOptions(ctx))
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "getStarredRepos", err)
 	}
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index 83f23db15..7765a399f 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -5,6 +5,7 @@
 package user
 
 import (
+	std_context "context"
 	"net/http"
 
 	"code.gitea.io/gitea/models/db"
@@ -18,15 +19,15 @@ import (
 )
 
 // getWatchedRepos returns the repos that the user with the specified userID is watching
-func getWatchedRepos(user *user_model.User, private bool, listOptions db.ListOptions) ([]*api.Repository, int64, error) {
-	watchedRepos, total, err := repo_model.GetWatchedRepos(user.ID, private, listOptions)
+func getWatchedRepos(ctx std_context.Context, user *user_model.User, private bool, listOptions db.ListOptions) ([]*api.Repository, int64, error) {
+	watchedRepos, total, err := repo_model.GetWatchedRepos(ctx, user.ID, private, listOptions)
 	if err != nil {
 		return nil, 0, err
 	}
 
 	repos := make([]*api.Repository, len(watchedRepos))
 	for i, watched := range watchedRepos {
-		access, err := access_model.AccessLevel(user, watched)
+		access, err := access_model.AccessLevel(ctx, user, watched)
 		if err != nil {
 			return nil, 0, err
 		}
@@ -61,7 +62,7 @@ func GetWatchedRepos(ctx *context.APIContext) {
 	//     "$ref": "#/responses/RepositoryList"
 
 	private := ctx.ContextUser.ID == ctx.Doer.ID
-	repos, total, err := getWatchedRepos(ctx.ContextUser, private, utils.GetListOptions(ctx))
+	repos, total, err := getWatchedRepos(ctx, ctx.ContextUser, private, utils.GetListOptions(ctx))
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err)
 	}
@@ -90,7 +91,7 @@ func GetMyWatchedRepos(ctx *context.APIContext) {
 	//   "200":
 	//     "$ref": "#/responses/RepositoryList"
 
-	repos, total, err := getWatchedRepos(ctx.Doer, true, utils.GetListOptions(ctx))
+	repos, total, err := getWatchedRepos(ctx, ctx.Doer, true, utils.GetListOptions(ctx))
 	if err != nil {
 		ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err)
 	}
diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go
index 93aa450f9..1370e5302 100644
--- a/routers/private/hook_post_receive.go
+++ b/routers/private/hook_post_receive.go
@@ -202,7 +202,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
 				continue
 			}
 
-			pr, err := issues_model.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, issues_model.PullRequestFlowGithub)
+			pr, err := issues_model.GetUnmergedPullRequest(ctx, repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, issues_model.PullRequestFlowGithub)
 			if err != nil && !issues_model.IsErrPullRequestNotExist(err) {
 				log.Error("Failed to get active PR in: %-v Branch: %s to: %-v Branch: %s Error: %v", repo, branch, baseRepo, baseRepo.DefaultBranch, err)
 				ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go
index fdd0a0bc3..86bdf60ab 100644
--- a/routers/private/hook_pre_receive.go
+++ b/routers/private/hook_pre_receive.go
@@ -372,7 +372,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName
 
 	if !ctx.gotProtectedTags {
 		var err error
-		ctx.protectedTags, err = git_model.GetProtectedTags(ctx.Repo.Repository.ID)
+		ctx.protectedTags, err = git_model.GetProtectedTags(ctx, ctx.Repo.Repository.ID)
 		if err != nil {
 			log.Error("Unable to get protected tags for %-v Error: %v", ctx.Repo.Repository, err)
 			ctx.JSON(http.StatusInternalServerError, private.Response{
@@ -383,7 +383,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName
 		ctx.gotProtectedTags = true
 	}
 
-	isAllowed, err := git_model.IsUserAllowedToControlTag(ctx.protectedTags, tagName, ctx.opts.UserID)
+	isAllowed, err := git_model.IsUserAllowedToControlTag(ctx, ctx.protectedTags, tagName, ctx.opts.UserID)
 	if err != nil {
 		ctx.JSON(http.StatusInternalServerError, private.Response{
 			Err: err.Error(),
diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go
index 8cb615b7b..8d4ecf1bc 100644
--- a/routers/web/explore/repo.go
+++ b/routers/web/explore/repo.go
@@ -98,7 +98,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
 	language := ctx.FormTrim("language")
 	ctx.Data["Language"] = language
 
-	repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			Page:     page,
 			PageSize: opts.PageSize,
diff --git a/routers/web/home.go b/routers/web/home.go
index 0c74987ba..7640243ba 100644
--- a/routers/web/home.go
+++ b/routers/web/home.go
@@ -88,7 +88,7 @@ func HomeSitemap(ctx *context.Context) {
 		}
 	}
 
-	_, cnt, err := repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	_, cnt, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			PageSize: 1,
 		},
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 63243a391..6bd8a89d1 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -99,7 +99,7 @@ func Home(ctx *context.Context) {
 		count int64
 		err   error
 	)
-	repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			PageSize: setting.UI.User.RepoPagingNum,
 			Page:     page,
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index d1f1255db..a7588d275 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -275,14 +275,14 @@ func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, p
 	mergeMovedOn := false
 	if pr != nil {
 		pr.HeadRepo = ctx.Repo.Repository
-		if err := pr.LoadIssue(); err != nil {
-			ctx.ServerError("pr.LoadIssue", err)
+		if err := pr.LoadIssue(ctx); err != nil {
+			ctx.ServerError("LoadIssue", err)
 			return nil
 		}
 		if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
 			pr.BaseRepo = repo
-		} else if err := pr.LoadBaseRepoCtx(ctx); err != nil {
-			ctx.ServerError("pr.LoadBaseRepo", err)
+		} else if err := pr.LoadBaseRepo(ctx); err != nil {
+			ctx.ServerError("LoadBaseRepo", err)
 			return nil
 		} else {
 			repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index db6b59471..0fb8e4472 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -747,7 +747,7 @@ func CompareDiff(ctx *context.Context) {
 	ctx.Data["HeadTags"] = headTags
 
 	if ctx.Data["PageIsComparePull"] == true {
-		pr, err := issues_model.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, issues_model.PullRequestFlowGithub)
+		pr, err := issues_model.GetUnmergedPullRequest(ctx, ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, issues_model.PullRequestFlowGithub)
 		if err != nil {
 			if !issues_model.IsErrPullRequestNotExist(err) {
 				ctx.ServerError("GetUnmergedPullRequest", err)
@@ -755,7 +755,7 @@ func CompareDiff(ctx *context.Context) {
 			}
 		} else {
 			ctx.Data["HasPullRequest"] = true
-			if err := pr.LoadIssue(); err != nil {
+			if err := pr.LoadIssue(ctx); err != nil {
 				ctx.ServerError("LoadIssue", err)
 				return
 			}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 38ad593c1..a62084fdc 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -246,7 +246,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
 	if forceEmpty {
 		issues = []*issues_model.Issue{}
 	} else {
-		issues, err = issues_model.Issues(&issues_model.IssuesOptions{
+		issues, err = issues_model.Issues(ctx, &issues_model.IssuesOptions{
 			ListOptions: db.ListOptions{
 				Page:     pager.Paginater.Current(),
 				PageSize: setting.UI.IssuePagingNum,
@@ -608,7 +608,7 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is
 		currentPullReviewers := make([]*repoReviewerSelection, 0, len(pullReviews))
 		for _, item := range pullReviews {
 			if item.Review.ReviewerID > 0 {
-				if err = item.Review.LoadReviewer(); err != nil {
+				if err = item.Review.LoadReviewer(ctx); err != nil {
 					if user_model.IsErrUserNotExist(err) {
 						continue
 					}
@@ -617,7 +617,7 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is
 				}
 				item.User = item.Review.Reviewer
 			} else if item.Review.ReviewerTeamID > 0 {
-				if err = item.Review.LoadReviewerTeam(); err != nil {
+				if err = item.Review.LoadReviewerTeam(ctx); err != nil {
 					if organization.IsErrTeamNotExist(err) {
 						continue
 					}
@@ -1163,7 +1163,7 @@ func getBranchData(ctx *context.Context, issue *issues_model.Issue) {
 		pull := issue.PullRequest
 		ctx.Data["BaseBranch"] = pull.BaseBranch
 		ctx.Data["HeadBranch"] = pull.HeadBranch
-		ctx.Data["HeadUserName"] = pull.MustHeadUserName()
+		ctx.Data["HeadUserName"] = pull.MustHeadUserName(ctx)
 	}
 }
 
@@ -1426,13 +1426,13 @@ func ViewIssue(ctx *context.Context) {
 	for _, comment = range issue.Comments {
 		comment.Issue = issue
 
-		if err := comment.LoadPoster(); err != nil {
+		if err := comment.LoadPoster(ctx); err != nil {
 			ctx.ServerError("LoadPoster", err)
 			return
 		}
 
 		if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview {
-			if err := comment.LoadAttachments(); err != nil {
+			if err := comment.LoadAttachments(ctx); err != nil {
 				ctx.ServerError("LoadAttachments", err)
 				return
 			}
@@ -1467,7 +1467,7 @@ func ViewIssue(ctx *context.Context) {
 				return
 			}
 		} else if comment.Type == issues_model.CommentTypeMilestone {
-			if err = comment.LoadMilestone(); err != nil {
+			if err = comment.LoadMilestone(ctx); err != nil {
 				ctx.ServerError("LoadMilestone", err)
 				return
 			}
@@ -1591,7 +1591,7 @@ func ViewIssue(ctx *context.Context) {
 		ctx.Data["AllowMerge"] = false
 
 		if ctx.IsSigned {
-			if err := pull.LoadHeadRepoCtx(ctx); err != nil {
+			if err := pull.LoadHeadRepo(ctx); err != nil {
 				log.Error("LoadHeadRepo: %v", err)
 			} else if pull.HeadRepo != nil {
 				perm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, ctx.Doer)
@@ -1613,7 +1613,7 @@ func ViewIssue(ctx *context.Context) {
 				}
 			}
 
-			if err := pull.LoadBaseRepoCtx(ctx); err != nil {
+			if err := pull.LoadBaseRepo(ctx); err != nil {
 				log.Error("LoadBaseRepo: %v", err)
 			}
 			perm, err := access_model.GetUserRepoPermission(ctx, pull.BaseRepo, ctx.Doer)
@@ -1662,14 +1662,14 @@ func ViewIssue(ctx *context.Context) {
 
 		ctx.Data["MergeStyle"] = mergeStyle
 
-		defaultMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pull, mergeStyle)
+		defaultMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle)
 		if err != nil {
 			ctx.ServerError("GetDefaultMergeMessage", err)
 			return
 		}
 		ctx.Data["DefaultMergeMessage"] = defaultMergeMessage
 
-		defaultSquashMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash)
+		defaultSquashMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash)
 		if err != nil {
 			ctx.ServerError("GetDefaultSquashMergeMessage", err)
 			return
@@ -1885,7 +1885,7 @@ func GetIssueInfo(ctx *context.Context) {
 		}
 	}
 
-	ctx.JSON(http.StatusOK, convert.ToAPIIssue(issue))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
 }
 
 // UpdateIssueTitle change issue's title
@@ -2280,7 +2280,7 @@ func SearchIssues(ctx *context.Context) {
 	repoCond := repo_model.SearchRepositoryCondition(opts)
 	repoIDs, _, err := repo_model.SearchRepositoryIDs(opts)
 	if err != nil {
-		ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err.Error())
+		ctx.Error(http.StatusInternalServerError, "SearchRepositoryIDs", err.Error())
 		return
 	}
 
@@ -2369,7 +2369,7 @@ func SearchIssues(ctx *context.Context) {
 			issuesOpt.ReviewRequestedID = ctxUserID
 		}
 
-		if issues, err = issues_model.Issues(issuesOpt); err != nil {
+		if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "Issues", err.Error())
 			return
 		}
@@ -2377,14 +2377,14 @@ func SearchIssues(ctx *context.Context) {
 		issuesOpt.ListOptions = db.ListOptions{
 			Page: -1,
 		}
-		if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil {
+		if filteredCount, err = issues_model.CountIssues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, "CountIssues", err.Error())
 			return
 		}
 	}
 
 	ctx.SetTotalCountHeader(filteredCount)
-	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
 }
 
 func getUserIDForFilter(ctx *context.Context, queryName string) int64 {
@@ -2527,7 +2527,7 @@ func ListIssues(ctx *context.Context) {
 			MentionedID:       mentionedByID,
 		}
 
-		if issues, err = issues_model.Issues(issuesOpt); err != nil {
+		if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, err.Error())
 			return
 		}
@@ -2535,14 +2535,14 @@ func ListIssues(ctx *context.Context) {
 		issuesOpt.ListOptions = db.ListOptions{
 			Page: -1,
 		}
-		if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil {
+		if filteredCount, err = issues_model.CountIssues(ctx, issuesOpt); err != nil {
 			ctx.Error(http.StatusInternalServerError, err.Error())
 			return
 		}
 	}
 
 	ctx.SetTotalCountHeader(filteredCount)
-	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
+	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
 }
 
 // UpdateIssueStatus change issue's status
@@ -2562,7 +2562,7 @@ func UpdateIssueStatus(ctx *context.Context) {
 		log.Warn("Unrecognized action: %s", action)
 	}
 
-	if _, err := issues_model.IssueList(issues).LoadRepositories(); err != nil {
+	if _, err := issues_model.IssueList(issues).LoadRepositories(ctx); err != nil {
 		ctx.ServerError("LoadRepositories", err)
 		return
 	}
@@ -2646,7 +2646,7 @@ func NewComment(ctx *context.Context) {
 			if form.Status == "reopen" && issue.IsPull {
 				pull := issue.PullRequest
 				var err error
-				pr, err = issues_model.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow)
+				pr, err = issues_model.GetUnmergedPullRequest(ctx, pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow)
 				if err != nil {
 					if !issues_model.IsErrPullRequestNotExist(err) {
 						ctx.ServerError("GetUnmergedPullRequest", err)
@@ -2706,7 +2706,7 @@ func NewComment(ctx *context.Context) {
 		return
 	}
 
-	comment, err := comment_service.CreateIssueComment(ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
+	comment, err := comment_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
 	if err != nil {
 		ctx.ServerError("CreateIssueComment", err)
 		return
@@ -2723,7 +2723,7 @@ func UpdateCommentContent(ctx *context.Context) {
 		return
 	}
 
-	if err := comment.LoadIssue(); err != nil {
+	if err := comment.LoadIssue(ctx); err != nil {
 		ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err)
 		return
 	}
@@ -2746,12 +2746,12 @@ func UpdateCommentContent(ctx *context.Context) {
 		})
 		return
 	}
-	if err = comment_service.UpdateComment(comment, ctx.Doer, oldContent); err != nil {
+	if err = comment_service.UpdateComment(ctx, comment, ctx.Doer, oldContent); err != nil {
 		ctx.ServerError("UpdateComment", err)
 		return
 	}
 
-	if err := comment.LoadAttachments(); err != nil {
+	if err := comment.LoadAttachments(ctx); err != nil {
 		ctx.ServerError("LoadAttachments", err)
 		return
 	}
@@ -2789,7 +2789,7 @@ func DeleteComment(ctx *context.Context) {
 		return
 	}
 
-	if err := comment.LoadIssue(); err != nil {
+	if err := comment.LoadIssue(ctx); err != nil {
 		ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err)
 		return
 	}
@@ -2802,8 +2802,8 @@ func DeleteComment(ctx *context.Context) {
 		return
 	}
 
-	if err = comment_service.DeleteComment(ctx.Doer, comment); err != nil {
-		ctx.ServerError("DeleteCommentByID", err)
+	if err = comment_service.DeleteComment(ctx, ctx.Doer, comment); err != nil {
+		ctx.ServerError("DeleteComment", err)
 		return
 	}
 
@@ -2915,7 +2915,7 @@ func ChangeCommentReaction(ctx *context.Context) {
 		return
 	}
 
-	if err := comment.LoadIssue(); err != nil {
+	if err := comment.LoadIssue(ctx); err != nil {
 		ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err)
 		return
 	}
@@ -3061,7 +3061,7 @@ func GetCommentAttachments(ctx *context.Context) {
 	}
 	attachments := make([]*api.Attachment, 0)
 	if comment.Type == issues_model.CommentTypeComment {
-		if err := comment.LoadAttachments(); err != nil {
+		if err := comment.LoadAttachments(ctx); err != nil {
 			ctx.ServerError("LoadAttachments", err)
 			return
 		}
diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go
index 7af415a8f..560f25a0a 100644
--- a/routers/web/repo/issue_label.go
+++ b/routers/web/repo/issue_label.go
@@ -75,7 +75,7 @@ func RetrieveLabels(ctx *context.Context) {
 			return
 		}
 		for _, l := range orgLabels {
-			l.CalOpenOrgIssues(ctx.Repo.Repository.ID, l.ID)
+			l.CalOpenOrgIssues(ctx, ctx.Repo.Repository.ID, l.ID)
 		}
 		ctx.Data["OrgLabels"] = orgLabels
 
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index f054ad6e5..fb2d25a22 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -297,7 +297,7 @@ func ViewProject(ctx *context.Context) {
 		boards[0].Title = ctx.Tr("repo.projects.type.uncategorized")
 	}
 
-	issuesMap, err := issues_model.LoadIssuesFromBoardList(boards)
+	issuesMap, err := issues_model.LoadIssuesFromBoardList(ctx, boards)
 	if err != nil {
 		ctx.ServerError("LoadIssuesOfBoards", err)
 		return
@@ -314,7 +314,7 @@ func ViewProject(ctx *context.Context) {
 			}
 
 			if len(referencedIds) > 0 {
-				if linkedPrs, err := issues_model.Issues(&issues_model.IssuesOptions{
+				if linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
 					IssueIDs: referencedIds,
 					IsPull:   util.OptionalBoolTrue,
 				}); err == nil {
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 41eac7cc3..870bc1773 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -281,7 +281,7 @@ func checkPullInfo(ctx *context.Context) *issues_model.Issue {
 		}
 		return nil
 	}
-	if err = issue.LoadPoster(); err != nil {
+	if err = issue.LoadPoster(ctx); err != nil {
 		ctx.ServerError("LoadPoster", err)
 		return nil
 	}
@@ -297,12 +297,12 @@ func checkPullInfo(ctx *context.Context) *issues_model.Issue {
 		return nil
 	}
 
-	if err = issue.LoadPullRequest(); err != nil {
+	if err = issue.LoadPullRequest(ctx); err != nil {
 		ctx.ServerError("LoadPullRequest", err)
 		return nil
 	}
 
-	if err = issue.PullRequest.LoadHeadRepoCtx(ctx); err != nil {
+	if err = issue.PullRequest.LoadHeadRepo(ctx); err != nil {
 		ctx.ServerError("LoadHeadRepo", err)
 		return nil
 	}
@@ -319,12 +319,12 @@ func checkPullInfo(ctx *context.Context) *issues_model.Issue {
 }
 
 func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) {
-	if ctx.Repo.Owner.Name == pull.MustHeadUserName() {
+	if ctx.Repo.Owner.Name == pull.MustHeadUserName(ctx) {
 		ctx.Data["HeadTarget"] = pull.HeadBranch
 	} else if pull.HeadRepo == nil {
-		ctx.Data["HeadTarget"] = pull.MustHeadUserName() + ":" + pull.HeadBranch
+		ctx.Data["HeadTarget"] = pull.MustHeadUserName(ctx) + ":" + pull.HeadBranch
 	} else {
-		ctx.Data["HeadTarget"] = pull.MustHeadUserName() + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
+		ctx.Data["HeadTarget"] = pull.MustHeadUserName(ctx) + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
 	}
 	ctx.Data["BaseTarget"] = pull.BaseBranch
 	ctx.Data["HeadBranchHTMLURL"] = pull.GetHeadBranchHTMLURL()
@@ -416,12 +416,12 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
 	repo := ctx.Repo.Repository
 	pull := issue.PullRequest
 
-	if err := pull.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pull.LoadHeadRepo(ctx); err != nil {
 		ctx.ServerError("LoadHeadRepo", err)
 		return nil
 	}
 
-	if err := pull.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pull.LoadBaseRepo(ctx); err != nil {
 		ctx.ServerError("LoadBaseRepo", err)
 		return nil
 	}
@@ -606,7 +606,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
 
 	if pull.IsWorkInProgress() {
 		ctx.Data["IsPullWorkInProgress"] = true
-		ctx.Data["WorkInProgressPrefix"] = pull.GetWorkInProgressPrefix()
+		ctx.Data["WorkInProgressPrefix"] = pull.GetWorkInProgressPrefix(ctx)
 	}
 
 	if pull.IsFilesConflicted() {
@@ -834,11 +834,11 @@ func UpdatePullRequest(ctx *context.Context) {
 
 	rebase := ctx.FormString("style") == "rebase"
 
-	if err := issue.PullRequest.LoadBaseRepoCtx(ctx); err != nil {
+	if err := issue.PullRequest.LoadBaseRepo(ctx); err != nil {
 		ctx.ServerError("LoadBaseRepo", err)
 		return
 	}
-	if err := issue.PullRequest.LoadHeadRepoCtx(ctx); err != nil {
+	if err := issue.PullRequest.LoadHeadRepo(ctx); err != nil {
 		ctx.ServerError("LoadHeadRepo", err)
 		return
 	}
@@ -974,7 +974,7 @@ func MergePullRequest(ctx *context.Context) {
 	message := strings.TrimSpace(form.MergeTitleField)
 	if len(message) == 0 {
 		var err error
-		message, err = pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do))
+		message, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do))
 		if err != nil {
 			ctx.ServerError("GetDefaultMergeMessage", err)
 			return
@@ -1296,14 +1296,14 @@ func CleanUpPullRequest(ctx *context.Context) {
 		return
 	}
 
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		ctx.ServerError("LoadHeadRepo", err)
 		return
 	} else if pr.HeadRepo == nil {
 		// Forked repository has already been deleted
 		ctx.NotFound("CleanUpPullRequest", nil)
 		return
-	} else if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	} else if err = pr.LoadBaseRepo(ctx); err != nil {
 		ctx.ServerError("LoadBaseRepo", err)
 		return
 	} else if err = pr.HeadRepo.GetOwner(ctx); err != nil {
@@ -1499,7 +1499,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
 		}
 		return
 	}
-	notification.NotifyPullRequestChangeTargetBranch(ctx.Doer, pr, targetBranch)
+	notification.NotifyPullRequestChangeTargetBranch(ctx, ctx.Doer, pr, targetBranch)
 
 	ctx.JSON(http.StatusOK, map[string]interface{}{
 		"base_branch": pr.BaseBranch,
diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go
index bc64f3547..bbaacc234 100644
--- a/routers/web/repo/pull_review.go
+++ b/routers/web/repo/pull_review.go
@@ -114,7 +114,7 @@ func UpdateResolveConversation(ctx *context.Context) {
 		return
 	}
 
-	if err = comment.LoadIssue(); err != nil {
+	if err = comment.LoadIssue(ctx); err != nil {
 		ctx.ServerError("comment.LoadIssue", err)
 		return
 	}
@@ -169,7 +169,7 @@ func renderConversation(ctx *context.Context, comment *issues_model.Comment) {
 	ctx.Data["comments"] = comments
 	ctx.Data["CanMarkConversation"] = true
 	ctx.Data["Issue"] = comment.Issue
-	if err = comment.Issue.LoadPullRequest(); err != nil {
+	if err = comment.Issue.LoadPullRequest(ctx); err != nil {
 		ctx.ServerError("comment.Issue.LoadPullRequest", err)
 		return
 	}
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 0cb85f379..0373d5b15 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -130,7 +130,7 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
 		opts.IncludeDrafts = writeAccess
 	}
 
-	releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts)
+	releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts)
 	if err != nil {
 		ctx.ServerError("GetReleasesByRepoID", err)
 		return
@@ -266,7 +266,7 @@ func LatestRelease(ctx *context.Context) {
 		return
 	}
 
-	if err := release.LoadAttributes(); err != nil {
+	if err := release.LoadAttributes(ctx); err != nil {
 		ctx.ServerError("LoadAttributes", err)
 		return
 	}
@@ -289,7 +289,7 @@ func NewRelease(ctx *context.Context) {
 
 		if rel != nil {
 			rel.Repo = ctx.Repo.Repository
-			if err := rel.LoadAttributes(); err != nil {
+			if err := rel.LoadAttributes(ctx); err != nil {
 				ctx.ServerError("LoadAttributes", err)
 				return
 			}
@@ -454,7 +454,7 @@ func EditRelease(ctx *context.Context) {
 	ctx.Data["IsDraft"] = rel.IsDraft
 
 	rel.Repo = ctx.Repo.Repository
-	if err := rel.LoadAttributes(); err != nil {
+	if err := rel.LoadAttributes(ctx); err != nil {
 		ctx.ServerError("LoadAttributes", err)
 		return
 	}
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 3e746d3f0..7bcca1d02 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -540,7 +540,7 @@ func SearchRepo(ctx *context.Context) {
 	}
 
 	var err error
-	repos, count, err := repo_model.SearchRepository(opts)
+	repos, count, err := repo_model.SearchRepository(ctx, opts)
 	if err != nil {
 		ctx.JSON(http.StatusInternalServerError, api.SearchError{
 			OK:    false,
diff --git a/routers/web/repo/tag.go b/routers/web/repo/tag.go
index f63a50782..4d46716c3 100644
--- a/routers/web/repo/tag.go
+++ b/routers/web/repo/tag.go
@@ -124,7 +124,7 @@ func DeleteProtectedTagPost(ctx *context.Context) {
 		return
 	}
 
-	if err := git_model.DeleteProtectedTag(pt); err != nil {
+	if err := git_model.DeleteProtectedTag(ctx, pt); err != nil {
 		ctx.ServerError("DeleteProtectedTag", err)
 		return
 	}
@@ -137,7 +137,7 @@ func setTagsContext(ctx *context.Context) error {
 	ctx.Data["Title"] = ctx.Tr("repo.settings")
 	ctx.Data["PageIsSettingsTags"] = true
 
-	protectedTags, err := git_model.GetProtectedTags(ctx.Repo.Repository.ID)
+	protectedTags, err := git_model.GetProtectedTags(ctx, ctx.Repo.Repository.ID)
 	if err != nil {
 		ctx.ServerError("GetProtectedTags", err)
 		return err
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index a10e12ee6..24d851762 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -706,7 +706,7 @@ func NewWikiPost(ctx *context.Context) {
 		return
 	}
 
-	notification.NotifyNewWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName, form.Message)
+	notification.NotifyNewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.Message)
 
 	ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(wikiName))
 }
@@ -750,7 +750,7 @@ func EditWikiPost(ctx *context.Context) {
 		return
 	}
 
-	notification.NotifyEditWikiPage(ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message)
+	notification.NotifyEditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message)
 
 	ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(newWikiName))
 }
@@ -767,7 +767,7 @@ func DeleteWikiPagePost(ctx *context.Context) {
 		return
 	}
 
-	notification.NotifyDeleteWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName)
+	notification.NotifyDeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName)
 
 	ctx.JSON(http.StatusOK, map[string]interface{}{
 		"redirect": ctx.Repo.RepoLink + "/wiki/",
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 95ec1aa2f..e67202b28 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -202,7 +202,7 @@ func Milestones(ctx *context.Context) {
 		return
 	}
 
-	showRepos, _, err := repo_model.SearchRepositoryByCondition(&repoOpts, userRepoCond, false)
+	showRepos, _, err := repo_model.SearchRepositoryByCondition(ctx, &repoOpts, userRepoCond, false)
 	if err != nil {
 		ctx.ServerError("SearchRepositoryByCondition", err)
 		return
@@ -461,7 +461,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
 	// USING NON-FINAL STATE OF opts FOR A QUERY.
 	var issueCountByRepo map[int64]int64
 	if !forceEmpty {
-		issueCountByRepo, err = issues_model.CountIssuesByRepo(opts)
+		issueCountByRepo, err = issues_model.CountIssuesByRepo(ctx, opts)
 		if err != nil {
 			ctx.ServerError("CountIssuesByRepo", err)
 			return
@@ -504,7 +504,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
 	// USING FINAL STATE OF opts FOR A QUERY.
 	var issues []*issues_model.Issue
 	if !forceEmpty {
-		issues, err = issues_model.Issues(opts)
+		issues, err = issues_model.Issues(ctx, opts)
 		if err != nil {
 			ctx.ServerError("Issues", err)
 			return
diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go
index b4753a603..323422a1b 100644
--- a/routers/web/user/notification.go
+++ b/routers/web/user/notification.go
@@ -33,20 +33,20 @@ const (
 )
 
 // GetNotificationCount is the middleware that sets the notification count in the context
-func GetNotificationCount(c *context.Context) {
-	if strings.HasPrefix(c.Req.URL.Path, "/api") {
+func GetNotificationCount(ctx *context.Context) {
+	if strings.HasPrefix(ctx.Req.URL.Path, "/api") {
 		return
 	}
 
-	if !c.IsSigned {
+	if !ctx.IsSigned {
 		return
 	}
 
-	c.Data["NotificationUnreadCount"] = func() int64 {
-		count, err := activities_model.GetNotificationCount(c, c.Doer, activities_model.NotificationStatusUnread)
+	ctx.Data["NotificationUnreadCount"] = func() int64 {
+		count, err := activities_model.GetNotificationCount(ctx, ctx.Doer, activities_model.NotificationStatusUnread)
 		if err != nil {
 			if err != goctx.Canceled {
-				log.Error("Unable to GetNotificationCount for user:%-v: %v", c.Doer, err)
+				log.Error("Unable to GetNotificationCount for user:%-v: %v", ctx.Doer, err)
 			}
 			return -1
 		}
@@ -56,25 +56,25 @@ func GetNotificationCount(c *context.Context) {
 }
 
 // Notifications is the notifications page
-func Notifications(c *context.Context) {
-	getNotifications(c)
-	if c.Written() {
+func Notifications(ctx *context.Context) {
+	getNotifications(ctx)
+	if ctx.Written() {
 		return
 	}
-	if c.FormBool("div-only") {
-		c.Data["SequenceNumber"] = c.FormString("sequence-number")
-		c.HTML(http.StatusOK, tplNotificationDiv)
+	if ctx.FormBool("div-only") {
+		ctx.Data["SequenceNumber"] = ctx.FormString("sequence-number")
+		ctx.HTML(http.StatusOK, tplNotificationDiv)
 		return
 	}
-	c.HTML(http.StatusOK, tplNotification)
+	ctx.HTML(http.StatusOK, tplNotification)
 }
 
-func getNotifications(c *context.Context) {
+func getNotifications(ctx *context.Context) {
 	var (
-		keyword = c.FormTrim("q")
+		keyword = ctx.FormTrim("q")
 		status  activities_model.NotificationStatus
-		page    = c.FormInt("page")
-		perPage = c.FormInt("perPage")
+		page    = ctx.FormInt("page")
+		perPage = ctx.FormInt("perPage")
 	)
 	if page < 1 {
 		page = 1
@@ -90,74 +90,74 @@ func getNotifications(c *context.Context) {
 		status = activities_model.NotificationStatusUnread
 	}
 
-	total, err := activities_model.GetNotificationCount(c, c.Doer, status)
+	total, err := activities_model.GetNotificationCount(ctx, ctx.Doer, status)
 	if err != nil {
-		c.ServerError("ErrGetNotificationCount", err)
+		ctx.ServerError("ErrGetNotificationCount", err)
 		return
 	}
 
 	// redirect to last page if request page is more than total pages
 	pager := context.NewPagination(int(total), perPage, page, 5)
 	if pager.Paginater.Current() < page {
-		c.Redirect(fmt.Sprintf("%s/notifications?q=%s&page=%d", setting.AppSubURL, url.QueryEscape(c.FormString("q")), pager.Paginater.Current()))
+		ctx.Redirect(fmt.Sprintf("%s/notifications?q=%s&page=%d", setting.AppSubURL, url.QueryEscape(ctx.FormString("q")), pager.Paginater.Current()))
 		return
 	}
 
 	statuses := []activities_model.NotificationStatus{status, activities_model.NotificationStatusPinned}
-	notifications, err := activities_model.NotificationsForUser(c, c.Doer, statuses, page, perPage)
+	notifications, err := activities_model.NotificationsForUser(ctx, ctx.Doer, statuses, page, perPage)
 	if err != nil {
-		c.ServerError("ErrNotificationsForUser", err)
+		ctx.ServerError("ErrNotificationsForUser", err)
 		return
 	}
 
 	failCount := 0
 
-	repos, failures, err := notifications.LoadRepos()
+	repos, failures, err := notifications.LoadRepos(ctx)
 	if err != nil {
-		c.ServerError("LoadRepos", err)
+		ctx.ServerError("LoadRepos", err)
 		return
 	}
 	notifications = notifications.Without(failures)
-	if err := repos.LoadAttributes(); err != nil {
-		c.ServerError("LoadAttributes", err)
+	if err := repos.LoadAttributes(); err != nil { // TODO
+		ctx.ServerError("LoadAttributes", err)
 		return
 	}
 	failCount += len(failures)
 
-	failures, err = notifications.LoadIssues()
+	failures, err = notifications.LoadIssues(ctx)
 	if err != nil {
-		c.ServerError("LoadIssues", err)
+		ctx.ServerError("LoadIssues", err)
 		return
 	}
 	notifications = notifications.Without(failures)
 	failCount += len(failures)
 
-	failures, err = notifications.LoadComments()
+	failures, err = notifications.LoadComments(ctx)
 	if err != nil {
-		c.ServerError("LoadComments", err)
+		ctx.ServerError("LoadComments", err)
 		return
 	}
 	notifications = notifications.Without(failures)
 	failCount += len(failures)
 
 	if failCount > 0 {
-		c.Flash.Error(fmt.Sprintf("ERROR: %d notifications were removed due to missing parts - check the logs", failCount))
+		ctx.Flash.Error(fmt.Sprintf("ERROR: %d notifications were removed due to missing parts - check the logs", failCount))
 	}
 
-	c.Data["Title"] = c.Tr("notifications")
-	c.Data["Keyword"] = keyword
-	c.Data["Status"] = status
-	c.Data["Notifications"] = notifications
+	ctx.Data["Title"] = ctx.Tr("notifications")
+	ctx.Data["Keyword"] = keyword
+	ctx.Data["Status"] = status
+	ctx.Data["Notifications"] = notifications
 
-	pager.SetDefaultParams(c)
-	c.Data["Page"] = pager
+	pager.SetDefaultParams(ctx)
+	ctx.Data["Page"] = pager
 }
 
 // NotificationStatusPost is a route for changing the status of a notification
-func NotificationStatusPost(c *context.Context) {
+func NotificationStatusPost(ctx *context.Context) {
 	var (
-		notificationID = c.FormInt64("notification_id")
-		statusStr      = c.FormString("status")
+		notificationID = ctx.FormInt64("notification_id")
+		statusStr      = ctx.FormString("status")
 		status         activities_model.NotificationStatus
 	)
 
@@ -169,56 +169,56 @@ func NotificationStatusPost(c *context.Context) {
 	case "pinned":
 		status = activities_model.NotificationStatusPinned
 	default:
-		c.ServerError("InvalidNotificationStatus", errors.New("Invalid notification status"))
+		ctx.ServerError("InvalidNotificationStatus", errors.New("Invalid notification status"))
 		return
 	}
 
-	if _, err := activities_model.SetNotificationStatus(notificationID, c.Doer, status); err != nil {
-		c.ServerError("SetNotificationStatus", err)
+	if _, err := activities_model.SetNotificationStatus(ctx, notificationID, ctx.Doer, status); err != nil {
+		ctx.ServerError("SetNotificationStatus", err)
 		return
 	}
 
-	if !c.FormBool("noredirect") {
-		url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, url.QueryEscape(c.FormString("page")))
-		c.Redirect(url, http.StatusSeeOther)
+	if !ctx.FormBool("noredirect") {
+		url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, url.QueryEscape(ctx.FormString("page")))
+		ctx.Redirect(url, http.StatusSeeOther)
 	}
 
-	getNotifications(c)
-	if c.Written() {
+	getNotifications(ctx)
+	if ctx.Written() {
 		return
 	}
-	c.Data["Link"] = setting.AppURL + "notifications"
-	c.Data["SequenceNumber"] = c.Req.PostFormValue("sequence-number")
+	ctx.Data["Link"] = setting.AppURL + "notifications"
+	ctx.Data["SequenceNumber"] = ctx.Req.PostFormValue("sequence-number")
 
-	c.HTML(http.StatusOK, tplNotificationDiv)
+	ctx.HTML(http.StatusOK, tplNotificationDiv)
 }
 
 // NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read
-func NotificationPurgePost(c *context.Context) {
-	err := activities_model.UpdateNotificationStatuses(c.Doer, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)
+func NotificationPurgePost(ctx *context.Context) {
+	err := activities_model.UpdateNotificationStatuses(ctx, ctx.Doer, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)
 	if err != nil {
-		c.ServerError("ErrUpdateNotificationStatuses", err)
+		ctx.ServerError("UpdateNotificationStatuses", err)
 		return
 	}
 
-	c.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther)
+	ctx.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther)
 }
 
 // NotificationSubscriptions returns the list of subscribed issues
-func NotificationSubscriptions(c *context.Context) {
-	page := c.FormInt("page")
+func NotificationSubscriptions(ctx *context.Context) {
+	page := ctx.FormInt("page")
 	if page < 1 {
 		page = 1
 	}
 
-	sortType := c.FormString("sort")
-	c.Data["SortType"] = sortType
+	sortType := ctx.FormString("sort")
+	ctx.Data["SortType"] = sortType
 
-	state := c.FormString("state")
+	state := ctx.FormString("state")
 	if !util.IsStringInSlice(state, []string{"all", "open", "closed"}, true) {
 		state = "all"
 	}
-	c.Data["State"] = state
+	ctx.Data["State"] = state
 	var showClosed util.OptionalBool
 	switch state {
 	case "all":
@@ -230,7 +230,7 @@ func NotificationSubscriptions(c *context.Context) {
 	}
 
 	var issueTypeBool util.OptionalBool
-	issueType := c.FormString("issueType")
+	issueType := ctx.FormString("issueType")
 	switch issueType {
 	case "issues":
 		issueTypeBool = util.OptionalBoolFalse
@@ -239,71 +239,71 @@ func NotificationSubscriptions(c *context.Context) {
 	default:
 		issueTypeBool = util.OptionalBoolNone
 	}
-	c.Data["IssueType"] = issueType
+	ctx.Data["IssueType"] = issueType
 
 	var labelIDs []int64
-	selectedLabels := c.FormString("labels")
-	c.Data["Labels"] = selectedLabels
+	selectedLabels := ctx.FormString("labels")
+	ctx.Data["Labels"] = selectedLabels
 	if len(selectedLabels) > 0 && selectedLabels != "0" {
 		var err error
 		labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ","))
 		if err != nil {
-			c.ServerError("StringsToInt64s", err)
+			ctx.ServerError("StringsToInt64s", err)
 			return
 		}
 	}
 
-	count, err := issues_model.CountIssues(&issues_model.IssuesOptions{
-		SubscriberID: c.Doer.ID,
+	count, err := issues_model.CountIssues(ctx, &issues_model.IssuesOptions{
+		SubscriberID: ctx.Doer.ID,
 		IsClosed:     showClosed,
 		IsPull:       issueTypeBool,
 		LabelIDs:     labelIDs,
 	})
 	if err != nil {
-		c.ServerError("CountIssues", err)
+		ctx.ServerError("CountIssues", err)
 		return
 	}
-	issues, err := issues_model.Issues(&issues_model.IssuesOptions{
+	issues, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
 		ListOptions: db.ListOptions{
 			PageSize: setting.UI.IssuePagingNum,
 			Page:     page,
 		},
-		SubscriberID: c.Doer.ID,
+		SubscriberID: ctx.Doer.ID,
 		SortType:     sortType,
 		IsClosed:     showClosed,
 		IsPull:       issueTypeBool,
 		LabelIDs:     labelIDs,
 	})
 	if err != nil {
-		c.ServerError("Issues", err)
+		ctx.ServerError("Issues", err)
 		return
 	}
 
-	commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(c, issues)
+	commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(ctx, issues)
 	if err != nil {
-		c.ServerError("GetIssuesAllCommitStatus", err)
+		ctx.ServerError("GetIssuesAllCommitStatus", err)
 		return
 	}
-	c.Data["CommitLastStatus"] = lastStatus
-	c.Data["CommitStatuses"] = commitStatuses
-	c.Data["Issues"] = issues
+	ctx.Data["CommitLastStatus"] = lastStatus
+	ctx.Data["CommitStatuses"] = commitStatuses
+	ctx.Data["Issues"] = issues
 
-	c.Data["IssueRefEndNames"], c.Data["IssueRefURLs"] = issue_service.GetRefEndNamesAndURLs(issues, "")
+	ctx.Data["IssueRefEndNames"], ctx.Data["IssueRefURLs"] = issue_service.GetRefEndNamesAndURLs(issues, "")
 
-	commitStatus, err := pull_service.GetIssuesLastCommitStatus(c, issues)
+	commitStatus, err := pull_service.GetIssuesLastCommitStatus(ctx, issues)
 	if err != nil {
-		c.ServerError("GetIssuesLastCommitStatus", err)
+		ctx.ServerError("GetIssuesLastCommitStatus", err)
 		return
 	}
-	c.Data["CommitStatus"] = commitStatus
+	ctx.Data["CommitStatus"] = commitStatus
 
 	issueList := issues_model.IssueList(issues)
-	approvalCounts, err := issueList.GetApprovalCounts(c)
+	approvalCounts, err := issueList.GetApprovalCounts(ctx)
 	if err != nil {
-		c.ServerError("ApprovalCounts", err)
+		ctx.ServerError("ApprovalCounts", err)
 		return
 	}
-	c.Data["ApprovalCounts"] = func(issueID int64, typ string) int64 {
+	ctx.Data["ApprovalCounts"] = func(issueID int64, typ string) int64 {
 		counts, ok := approvalCounts[issueID]
 		if !ok || len(counts) == 0 {
 			return 0
@@ -322,32 +322,32 @@ func NotificationSubscriptions(c *context.Context) {
 		return 0
 	}
 
-	c.Data["Status"] = 1
-	c.Data["Title"] = c.Tr("notification.subscriptions")
+	ctx.Data["Status"] = 1
+	ctx.Data["Title"] = ctx.Tr("notification.subscriptions")
 
 	// redirect to last page if request page is more than total pages
 	pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
 	if pager.Paginater.Current() < page {
-		c.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginater.Current()))
+		ctx.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginater.Current()))
 		return
 	}
-	pager.AddParam(c, "sort", "SortType")
-	pager.AddParam(c, "state", "State")
-	c.Data["Page"] = pager
+	pager.AddParam(ctx, "sort", "SortType")
+	pager.AddParam(ctx, "state", "State")
+	ctx.Data["Page"] = pager
 
-	c.HTML(http.StatusOK, tplNotificationSubscriptions)
+	ctx.HTML(http.StatusOK, tplNotificationSubscriptions)
 }
 
 // NotificationWatching returns the list of watching repos
-func NotificationWatching(c *context.Context) {
-	page := c.FormInt("page")
+func NotificationWatching(ctx *context.Context) {
+	page := ctx.FormInt("page")
 	if page < 1 {
 		page = 1
 	}
 
 	var orderBy db.SearchOrderBy
-	c.Data["SortType"] = c.FormString("sort")
-	switch c.FormString("sort") {
+	ctx.Data["SortType"] = ctx.FormString("sort")
+	switch ctx.FormString("sort") {
 	case "newest":
 		orderBy = db.SearchOrderByNewest
 	case "oldest":
@@ -369,41 +369,41 @@ func NotificationWatching(c *context.Context) {
 	case "fewestforks":
 		orderBy = db.SearchOrderByForks
 	default:
-		c.Data["SortType"] = "recentupdate"
+		ctx.Data["SortType"] = "recentupdate"
 		orderBy = db.SearchOrderByRecentUpdated
 	}
 
-	repos, count, err := repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+	repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 		ListOptions: db.ListOptions{
 			PageSize: setting.UI.User.RepoPagingNum,
 			Page:     page,
 		},
-		Actor:              c.Doer,
-		Keyword:            c.FormTrim("q"),
+		Actor:              ctx.Doer,
+		Keyword:            ctx.FormTrim("q"),
 		OrderBy:            orderBy,
-		Private:            c.IsSigned,
-		WatchedByID:        c.Doer.ID,
+		Private:            ctx.IsSigned,
+		WatchedByID:        ctx.Doer.ID,
 		Collaborate:        util.OptionalBoolFalse,
-		TopicOnly:          c.FormBool("topic"),
+		TopicOnly:          ctx.FormBool("topic"),
 		IncludeDescription: setting.UI.SearchRepoDescription,
 	})
 	if err != nil {
-		c.ServerError("ErrSearchRepository", err)
+		ctx.ServerError("SearchRepository", err)
 		return
 	}
 	total := int(count)
-	c.Data["Total"] = total
-	c.Data["Repos"] = repos
+	ctx.Data["Total"] = total
+	ctx.Data["Repos"] = repos
 
 	// redirect to last page if request page is more than total pages
 	pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
-	pager.SetDefaultParams(c)
-	c.Data["Page"] = pager
+	pager.SetDefaultParams(ctx)
+	ctx.Data["Page"] = pager
 
-	c.Data["Status"] = 2
-	c.Data["Title"] = c.Tr("notification.watching")
+	ctx.Data["Status"] = 2
+	ctx.Data["Title"] = ctx.Tr("notification.watching")
 
-	c.HTML(http.StatusOK, tplNotificationSubscriptions)
+	ctx.HTML(http.StatusOK, tplNotificationSubscriptions)
 }
 
 // NewAvailable returns the notification counts
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 6e16b377d..982290e0a 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -203,7 +203,7 @@ func Profile(ctx *context.Context) {
 		}
 	case "stars":
 		ctx.Data["PageIsProfileStarList"] = true
-		repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+		repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 			ListOptions: db.ListOptions{
 				PageSize: setting.UI.User.RepoPagingNum,
 				Page:     page,
@@ -235,7 +235,7 @@ func Profile(ctx *context.Context) {
 			return
 		}
 	case "watching":
-		repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+		repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 			ListOptions: db.ListOptions{
 				PageSize: setting.UI.User.RepoPagingNum,
 				Page:     page,
@@ -257,7 +257,7 @@ func Profile(ctx *context.Context) {
 
 		total = int(count)
 	default:
-		repos, count, err = repo_model.SearchRepository(&repo_model.SearchRepoOptions{
+		repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 			ListOptions: db.ListOptions{
 				PageSize: setting.UI.User.RepoPagingNum,
 				Page:     page,
diff --git a/services/agit/agit.go b/services/agit/agit.go
index a7e701d6c..803ff696b 100644
--- a/services/agit/agit.go
+++ b/services/agit/agit.go
@@ -96,7 +96,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
 			headBranch = curentTopicBranch
 		}
 
-		pr, err := issues_model.GetUnmergedPullRequest(repo.ID, repo.ID, headBranch, baseBranchName, issues_model.PullRequestFlowAGit)
+		pr, err := issues_model.GetUnmergedPullRequest(ctx, repo.ID, repo.ID, headBranch, baseBranchName, issues_model.PullRequestFlowAGit)
 		if err != nil {
 			if !issues_model.IsErrPullRequestNotExist(err) {
 				return nil, fmt.Errorf("Failed to get unmerged agit flow pull request in repository: %s/%s Error: %w", ownerName, repoName, err)
@@ -159,7 +159,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
 		}
 
 		// update exist pull request
-		if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+		if err := pr.LoadBaseRepo(ctx); err != nil {
 			return nil, fmt.Errorf("Unable to load base repository for PR[%d] Error: %w", pr.ID, err)
 		}
 
@@ -203,15 +203,15 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
 		if err != nil {
 			return nil, fmt.Errorf("Failed to get user. Error: %w", err)
 		}
-		err = pr.LoadIssue()
+		err = pr.LoadIssue(ctx)
 		if err != nil {
 			return nil, fmt.Errorf("Failed to load pull issue. Error: %w", err)
 		}
 		comment, err := issues_model.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i])
 		if err == nil && comment != nil {
-			notification.NotifyPullRequestPushCommits(pusher, pr, comment)
+			notification.NotifyPullRequestPushCommits(ctx, pusher, pr, comment)
 		}
-		notification.NotifyPullRequestSynchronized(pusher, pr)
+		notification.NotifyPullRequestSynchronized(ctx, pusher, pr)
 		isForcePush := comment != nil && comment.IsForcePush
 
 		results = append(results, private.HookProcReceiveRefResult{
diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go
index edfd0f6ca..a9d1e179a 100644
--- a/services/asymkey/sign.go
+++ b/services/asymkey/sign.go
@@ -272,7 +272,7 @@ Loop:
 
 // SignMerge determines if we should sign a PR merge commit to the base repository
 func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) {
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("Unable to get Base Repo for pull request")
 		return false, "", nil, err
 	}
diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go
index 5c38367e3..3291ed31f 100644
--- a/services/automerge/automerge.go
+++ b/services/automerge/automerge.go
@@ -188,8 +188,8 @@ func handlePull(pullID int64, sha string) {
 	// We get the latest sha commit hash again to handle the case where the check of a previous push
 	// did not succeed or was not finished yet.
 
-	if err = pr.LoadHeadRepoCtx(ctx); err != nil {
-		log.Error("pull[%d] LoadHeadRepoCtx: %v", pr.ID, err)
+	if err = pr.LoadHeadRepo(ctx); err != nil {
+		log.Error("pull[%d] LoadHeadRepo: %v", pr.ID, err)
 		return
 	}
 
@@ -244,8 +244,8 @@ func handlePull(pullID int64, sha string) {
 	if pr.BaseRepoID == pr.HeadRepoID {
 		baseGitRepo = headGitRepo
 	} else {
-		if err = pr.LoadBaseRepoCtx(ctx); err != nil {
-			log.Error("LoadBaseRepoCtx: %v", err)
+		if err = pr.LoadBaseRepo(ctx); err != nil {
+			log.Error("LoadBaseRepo: %v", err)
 			return
 		}
 
diff --git a/services/comments/comments.go b/services/comments/comments.go
index 7167219c2..190b8a672 100644
--- a/services/comments/comments.go
+++ b/services/comments/comments.go
@@ -5,6 +5,8 @@
 package comments
 
 import (
+	"context"
+
 	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -14,7 +16,7 @@ import (
 )
 
 // CreateIssueComment creates a plain issue comment.
-func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) {
+func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) {
 	comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{
 		Type:        issues_model.CommentTypeComment,
 		Doer:        doer,
@@ -27,27 +29,27 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu
 		return nil, err
 	}
 
-	mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content)
+	mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content)
 	if err != nil {
 		return nil, err
 	}
 
-	notification.NotifyCreateIssueComment(doer, repo, issue, comment, mentions)
+	notification.NotifyCreateIssueComment(ctx, doer, repo, issue, comment, mentions)
 
 	return comment, nil
 }
 
 // UpdateComment updates information of comment.
-func UpdateComment(c *issues_model.Comment, doer *user_model.User, oldContent string) error {
+func UpdateComment(ctx context.Context, c *issues_model.Comment, doer *user_model.User, oldContent string) error {
 	needsContentHistory := c.Content != oldContent &&
 		(c.Type == issues_model.CommentTypeComment || c.Type == issues_model.CommentTypeReview || c.Type == issues_model.CommentTypeCode)
 	if needsContentHistory {
-		hasContentHistory, err := issues_model.HasIssueContentHistory(db.DefaultContext, c.IssueID, c.ID)
+		hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, c.IssueID, c.ID)
 		if err != nil {
 			return err
 		}
 		if !hasContentHistory {
-			if err = issues_model.SaveIssueContentHistory(db.DefaultContext, c.PosterID, c.IssueID, c.ID,
+			if err = issues_model.SaveIssueContentHistory(ctx, c.PosterID, c.IssueID, c.ID,
 				c.CreatedUnix, oldContent, true); err != nil {
 				return err
 			}
@@ -59,33 +61,27 @@ func UpdateComment(c *issues_model.Comment, doer *user_model.User, oldContent st
 	}
 
 	if needsContentHistory {
-		err := issues_model.SaveIssueContentHistory(db.DefaultContext, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false)
+		err := issues_model.SaveIssueContentHistory(ctx, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false)
 		if err != nil {
 			return err
 		}
 	}
 
-	notification.NotifyUpdateComment(doer, c, oldContent)
+	notification.NotifyUpdateComment(ctx, doer, c, oldContent)
 
 	return nil
 }
 
 // DeleteComment deletes the comment
-func DeleteComment(doer *user_model.User, comment *issues_model.Comment) error {
-	ctx, committer, err := db.TxContext(db.DefaultContext)
+func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
+	err := db.AutoTx(ctx, func(ctx context.Context) error {
+		return issues_model.DeleteComment(ctx, comment)
+	})
 	if err != nil {
 		return err
 	}
-	defer committer.Close()
 
-	if err := issues_model.DeleteComment(ctx, comment); err != nil {
-		return err
-	}
-	if err := committer.Commit(); err != nil {
-		return err
-	}
-
-	notification.NotifyDeleteComment(doer, comment)
+	notification.NotifyDeleteComment(ctx, doer, comment)
 
 	return nil
 }
diff --git a/services/issue/assignee.go b/services/issue/assignee.go
index e24f8500c..291fc3163 100644
--- a/services/issue/assignee.go
+++ b/services/issue/assignee.go
@@ -51,13 +51,13 @@ func ToggleAssignee(issue *issues_model.Issue, doer *user_model.User, assigneeID
 		return
 	}
 
-	assignee, err1 := user_model.GetUserByID(assigneeID)
+	assignee, err1 := user_model.GetUserByIDCtx(db.DefaultContext, assigneeID)
 	if err1 != nil {
 		err = err1
 		return
 	}
 
-	notification.NotifyIssueChangeAssignee(doer, issue, assignee, removed, comment)
+	notification.NotifyIssueChangeAssignee(db.DefaultContext, doer, issue, assignee, removed, comment)
 
 	return removed, comment, err
 }
@@ -75,7 +75,7 @@ func ReviewRequest(issue *issues_model.Issue, doer, reviewer *user_model.User, i
 	}
 
 	if comment != nil {
-		notification.NotifyPullReviewRequest(doer, issue, reviewer, isAdd, comment)
+		notification.NotifyPullReviewRequest(db.DefaultContext, doer, issue, reviewer, isAdd, comment)
 	}
 
 	return comment, err
@@ -246,7 +246,7 @@ func TeamReviewRequest(issue *issues_model.Issue, doer *user_model.User, reviewe
 	}
 
 	// notify all user in this team
-	if err = comment.LoadIssue(); err != nil {
+	if err = comment.LoadIssue(db.DefaultContext); err != nil {
 		return
 	}
 
@@ -262,7 +262,7 @@ func TeamReviewRequest(issue *issues_model.Issue, doer *user_model.User, reviewe
 			continue
 		}
 		comment.AssigneeID = member.ID
-		notification.NotifyPullReviewRequest(doer, issue, member, isAdd, comment)
+		notification.NotifyPullReviewRequest(db.DefaultContext, doer, issue, member, isAdd, comment)
 	}
 
 	return comment, err
diff --git a/services/issue/content.go b/services/issue/content.go
index 6f493892f..851d986de 100644
--- a/services/issue/content.go
+++ b/services/issue/content.go
@@ -5,6 +5,7 @@
 package issue
 
 import (
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/notification"
@@ -18,7 +19,7 @@ func ChangeContent(issue *issues_model.Issue, doer *user_model.User, content str
 		return err
 	}
 
-	notification.NotifyIssueChangeContent(doer, issue, oldContent)
+	notification.NotifyIssueChangeContent(db.DefaultContext, doer, issue, oldContent)
 
 	return nil
 }
diff --git a/services/issue/issue.go b/services/issue/issue.go
index 8342d7f5d..ba9b17a0c 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -38,12 +38,12 @@ func NewIssue(repo *repo_model.Repository, issue *issues_model.Issue, labelIDs [
 		return err
 	}
 
-	notification.NotifyNewIssue(issue, mentions)
+	notification.NotifyNewIssue(db.DefaultContext, issue, mentions)
 	if len(issue.Labels) > 0 {
-		notification.NotifyIssueChangeLabels(issue.Poster, issue, issue.Labels, nil)
+		notification.NotifyIssueChangeLabels(db.DefaultContext, issue.Poster, issue, issue.Labels, nil)
 	}
 	if issue.Milestone != nil {
-		notification.NotifyIssueChangeMilestone(issue.Poster, issue, 0)
+		notification.NotifyIssueChangeMilestone(db.DefaultContext, issue.Poster, issue, 0)
 	}
 
 	return nil
@@ -58,7 +58,7 @@ func ChangeTitle(issue *issues_model.Issue, doer *user_model.User, title string)
 		return
 	}
 
-	notification.NotifyIssueChangeTitle(doer, issue, oldTitle)
+	notification.NotifyIssueChangeTitle(db.DefaultContext, doer, issue, oldTitle)
 
 	return nil
 }
@@ -72,7 +72,7 @@ func ChangeIssueRef(issue *issues_model.Issue, doer *user_model.User, ref string
 		return err
 	}
 
-	notification.NotifyIssueChangeRef(doer, issue, oldRef)
+	notification.NotifyIssueChangeRef(db.DefaultContext, doer, issue, oldRef)
 
 	return nil
 }
@@ -135,10 +135,10 @@ func UpdateAssignees(issue *issues_model.Issue, oneAssignee string, multipleAssi
 // DeleteIssue deletes an issue
 func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue) error {
 	// load issue before deleting it
-	if err := issue.LoadAttributes(db.DefaultContext); err != nil {
+	if err := issue.LoadAttributes(gitRepo.Ctx); err != nil {
 		return err
 	}
-	if err := issue.LoadPullRequest(); err != nil {
+	if err := issue.LoadPullRequest(gitRepo.Ctx); err != nil {
 		return err
 	}
 
@@ -154,7 +154,7 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *issues_m
 		}
 	}
 
-	notification.NotifyDeleteIssue(doer, issue)
+	notification.NotifyDeleteIssue(gitRepo.Ctx, doer, issue)
 
 	return nil
 }
@@ -162,7 +162,7 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *issues_m
 // AddAssigneeIfNotAssigned adds an assignee only if he isn't already assigned to the issue.
 // Also checks for access of assigned user
 func AddAssigneeIfNotAssigned(issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (err error) {
-	assignee, err := user_model.GetUserByID(assigneeID)
+	assignee, err := user_model.GetUserByIDCtx(db.DefaultContext, assigneeID)
 	if err != nil {
 		return err
 	}
diff --git a/services/issue/label.go b/services/issue/label.go
index a9a0c20b0..cd29fceba 100644
--- a/services/issue/label.go
+++ b/services/issue/label.go
@@ -18,7 +18,7 @@ func ClearLabels(issue *issues_model.Issue, doer *user_model.User) (err error) {
 		return
 	}
 
-	notification.NotifyIssueClearLabels(doer, issue)
+	notification.NotifyIssueClearLabels(db.DefaultContext, doer, issue)
 
 	return nil
 }
@@ -29,7 +29,7 @@ func AddLabel(issue *issues_model.Issue, doer *user_model.User, label *issues_mo
 		return err
 	}
 
-	notification.NotifyIssueChangeLabels(doer, issue, []*issues_model.Label{label}, nil)
+	notification.NotifyIssueChangeLabels(db.DefaultContext, doer, issue, []*issues_model.Label{label}, nil)
 	return nil
 }
 
@@ -39,7 +39,7 @@ func AddLabels(issue *issues_model.Issue, doer *user_model.User, labels []*issue
 		return err
 	}
 
-	notification.NotifyIssueChangeLabels(doer, issue, labels, nil)
+	notification.NotifyIssueChangeLabels(db.DefaultContext, doer, issue, labels, nil)
 	return nil
 }
 
@@ -74,7 +74,7 @@ func RemoveLabel(issue *issues_model.Issue, doer *user_model.User, label *issues
 		return err
 	}
 
-	notification.NotifyIssueChangeLabels(doer, issue, nil, []*issues_model.Label{label})
+	notification.NotifyIssueChangeLabels(db.DefaultContext, doer, issue, nil, []*issues_model.Label{label})
 	return nil
 }
 
@@ -89,6 +89,6 @@ func ReplaceLabels(issue *issues_model.Issue, doer *user_model.User, labels []*i
 		return err
 	}
 
-	notification.NotifyIssueChangeLabels(doer, issue, labels, old)
+	notification.NotifyIssueChangeLabels(db.DefaultContext, doer, issue, labels, old)
 	return nil
 }
diff --git a/services/issue/milestone.go b/services/issue/milestone.go
index 965b07556..2be4a9e70 100644
--- a/services/issue/milestone.go
+++ b/services/issue/milestone.go
@@ -79,7 +79,7 @@ func ChangeMilestoneAssign(issue *issues_model.Issue, doer *user_model.User, old
 		return fmt.Errorf("Commit: %w", err)
 	}
 
-	notification.NotifyIssueChangeMilestone(doer, issue, oldMilestoneID)
+	notification.NotifyIssueChangeMilestone(db.DefaultContext, doer, issue, oldMilestoneID)
 
 	return nil
 }
diff --git a/services/issue/status.go b/services/issue/status.go
index 0da5c8876..2d4622324 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -38,7 +38,7 @@ func changeStatusCtx(ctx context.Context, issue *issues_model.Issue, doer *user_
 		}
 	}
 
-	notification.NotifyIssueChangeStatus(doer, issue, comment, closed)
+	notification.NotifyIssueChangeStatus(ctx, doer, issue, comment, closed)
 
 	return nil
 }
diff --git a/services/lfs/locks.go b/services/lfs/locks.go
index e87589d12..45ba8faac 100644
--- a/services/lfs/locks.go
+++ b/services/lfs/locks.go
@@ -57,7 +57,7 @@ func GetListLockHandler(ctx *context.Context) {
 		})
 		return
 	}
-	repository.MustOwner()
+	repository.MustOwner(ctx)
 
 	authenticated := authenticate(ctx, repository, rv.Authorization, true, false)
 	if !authenticated {
@@ -144,7 +144,7 @@ func PostLockHandler(ctx *context.Context) {
 		})
 		return
 	}
-	repository.MustOwner()
+	repository.MustOwner(ctx)
 
 	authenticated := authenticate(ctx, repository, authorization, true, true)
 	if !authenticated {
@@ -211,7 +211,7 @@ func VerifyLockHandler(ctx *context.Context) {
 		})
 		return
 	}
-	repository.MustOwner()
+	repository.MustOwner(ctx)
 
 	authenticated := authenticate(ctx, repository, authorization, true, true)
 	if !authenticated {
@@ -277,7 +277,7 @@ func UnLockHandler(ctx *context.Context) {
 		})
 		return
 	}
-	repository.MustOwner()
+	repository.MustOwner(ctx)
 
 	authenticated := authenticate(ctx, repository, authorization, true, true)
 	if !authenticated {
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index 85a7d107e..a9e36e10f 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -18,7 +18,6 @@ import (
 	"time"
 
 	activities_model "code.gitea.io/gitea/models/activities"
-	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
@@ -265,7 +264,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
 		"Issue":           ctx.Issue,
 		"Comment":         ctx.Comment,
 		"IsPull":          ctx.Issue.IsPull,
-		"User":            ctx.Issue.Repo.MustOwner(),
+		"User":            ctx.Issue.Repo.MustOwner(ctx),
 		"Repo":            ctx.Issue.Repo.FullName(),
 		"Doer":            ctx.Doer,
 		"IsMention":       fromMention,
@@ -395,13 +394,13 @@ func sanitizeSubject(subject string) string {
 }
 
 // SendIssueAssignedMail composes and sends issue assigned email
-func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, content string, comment *issues_model.Comment, recipients []*user_model.User) error {
+func SendIssueAssignedMail(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, content string, comment *issues_model.Comment, recipients []*user_model.User) error {
 	if setting.MailService == nil {
 		// No mail service configured
 		return nil
 	}
 
-	if err := issue.LoadRepo(db.DefaultContext); err != nil {
+	if err := issue.LoadRepo(ctx); err != nil {
 		log.Error("Unable to load repo [%d] for issue #%d [%d]. Error: %v", issue.RepoID, issue.Index, issue.ID, err)
 		return err
 	}
@@ -417,7 +416,7 @@ func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, con
 
 	for lang, tos := range langMap {
 		msgs, err := composeIssueCommentMessages(&mailCommentContext{
-			Context:    context.TODO(), // TODO: use a correct context
+			Context:    ctx,
 			Issue:      issue,
 			Doer:       doer,
 			ActionType: activities_model.ActionType(0),
diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go
index 61e276805..e7ff1d59d 100644
--- a/services/mailer/mail_issue.go
+++ b/services/mailer/mail_issue.go
@@ -45,13 +45,13 @@ const (
 func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_model.User) error {
 	// Required by the mail composer; make sure to load these before calling the async function
 	if err := ctx.Issue.LoadRepo(ctx); err != nil {
-		return fmt.Errorf("LoadRepo(): %w", err)
+		return fmt.Errorf("LoadRepo: %w", err)
 	}
-	if err := ctx.Issue.LoadPoster(); err != nil {
-		return fmt.Errorf("LoadPoster(): %w", err)
+	if err := ctx.Issue.LoadPoster(ctx); err != nil {
+		return fmt.Errorf("LoadPoster: %w", err)
 	}
-	if err := ctx.Issue.LoadPullRequest(); err != nil {
-		return fmt.Errorf("LoadPullRequest(): %w", err)
+	if err := ctx.Issue.LoadPullRequest(ctx); err != nil {
+		return fmt.Errorf("LoadPullRequest: %w", err)
 	}
 
 	// Enough room to avoid reallocations
@@ -61,14 +61,14 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo
 	unfiltered[0] = ctx.Issue.PosterID
 
 	// =========== Assignees ===========
-	ids, err := issues_model.GetAssigneeIDsByIssue(ctx.Issue.ID)
+	ids, err := issues_model.GetAssigneeIDsByIssue(ctx, ctx.Issue.ID)
 	if err != nil {
 		return fmt.Errorf("GetAssigneeIDsByIssue(%d): %w", ctx.Issue.ID, err)
 	}
 	unfiltered = append(unfiltered, ids...)
 
 	// =========== Participants (i.e. commenters, reviewers) ===========
-	ids, err = issues_model.GetParticipantsIDsByIssueID(ctx.Issue.ID)
+	ids, err = issues_model.GetParticipantsIDsByIssueID(ctx, ctx.Issue.ID)
 	if err != nil {
 		return fmt.Errorf("GetParticipantsIDsByIssueID(%d): %w", ctx.Issue.ID, err)
 	}
@@ -110,7 +110,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo
 	}
 	visited.AddMultiple(ids...)
 
-	unfilteredUsers, err := user_model.GetMaileableUsersByIDs(unfiltered, false)
+	unfilteredUsers, err := user_model.GetMaileableUsersByIDs(ctx, unfiltered, false)
 	if err != nil {
 		return err
 	}
@@ -173,7 +173,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
 
 // MailParticipants sends new issue thread created emails to repository watchers
 // and mentioned people.
-func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType activities_model.ActionType, mentions []*user_model.User) error {
+func MailParticipants(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, opType activities_model.ActionType, mentions []*user_model.User) error {
 	if setting.MailService == nil {
 		// No mail service configured
 		return nil
@@ -188,7 +188,7 @@ func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType a
 	forceDoerNotification := opType == activities_model.ActionAutoMergePullRequest
 	if err := mailIssueCommentToParticipants(
 		&mailCommentContext{
-			Context:               context.TODO(), // TODO: use a correct context
+			Context:               ctx,
 			Issue:                 issue,
 			Doer:                  doer,
 			ActionType:            opType,
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 6df3fbbf1..b15fc05ce 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -36,7 +36,7 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
 		return
 	}
 
-	recipients, err := user_model.GetMaileableUsersByIDs(watcherIDList, false)
+	recipients, err := user_model.GetMaileableUsersByIDs(ctx, watcherIDList, false)
 	if err != nil {
 		log.Error("user_model.GetMaileableUsersByIDs: %v", err)
 		return
diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go
index 6fe9df092..d3f512092 100644
--- a/services/mailer/mail_repo.go
+++ b/services/mailer/mail_repo.go
@@ -6,9 +6,9 @@ package mailer
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 
-	"code.gitea.io/gitea/models/db"
 	"code.gitea.io/gitea/models/organization"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
@@ -18,14 +18,14 @@ import (
 )
 
 // SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created
-func SendRepoTransferNotifyMail(doer, newOwner *user_model.User, repo *repo_model.Repository) error {
+func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error {
 	if setting.MailService == nil {
 		// No mail service configured
 		return nil
 	}
 
 	if newOwner.IsOrganization() {
-		users, err := organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, newOwner.ID)
+		users, err := organization.GetUsersWhoCanCreateOrgRepo(ctx, newOwner.ID)
 		if err != nil {
 			return err
 		}
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index 68a7182b0..362492631 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -84,7 +84,7 @@ func TestGiteaUploadRepo(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, labels, 12)
 
-	releases, err := repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{
+	releases, err := repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{
 		ListOptions: db.ListOptions{
 			PageSize: 10,
 			Page:     0,
@@ -94,7 +94,7 @@ func TestGiteaUploadRepo(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, releases, 8)
 
-	releases, err = repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{
+	releases, err = repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{
 		ListOptions: db.ListOptions{
 			PageSize: 10,
 			Page:     0,
@@ -104,14 +104,14 @@ func TestGiteaUploadRepo(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, releases, 1)
 
-	issues, err := issues_model.Issues(&issues_model.IssuesOptions{
+	issues, err := issues_model.Issues(db.DefaultContext, &issues_model.IssuesOptions{
 		RepoID:   repo.ID,
 		IsPull:   util.OptionalBoolFalse,
 		SortType: "oldest",
 	})
 	assert.NoError(t, err)
 	assert.Len(t, issues, 15)
-	assert.NoError(t, issues[0].LoadDiscussComments())
+	assert.NoError(t, issues[0].LoadDiscussComments(db.DefaultContext))
 	assert.Empty(t, issues[0].Comments)
 
 	pulls, _, err := issues_model.PullRequests(repo.ID, &issues_model.PullRequestsOptions{
@@ -119,8 +119,8 @@ func TestGiteaUploadRepo(t *testing.T) {
 	})
 	assert.NoError(t, err)
 	assert.Len(t, pulls, 30)
-	assert.NoError(t, pulls[0].LoadIssue())
-	assert.NoError(t, pulls[0].Issue.LoadDiscussComments())
+	assert.NoError(t, pulls[0].LoadIssue(db.DefaultContext))
+	assert.NoError(t, pulls[0].Issue.LoadDiscussComments(db.DefaultContext))
 	assert.Len(t, pulls[0].Issue.Comments, 2)
 }
 
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index 6002e6b8e..4a77569d8 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -459,18 +459,18 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
 				log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err)
 				continue
 			}
-			notification.NotifySyncPushCommits(m.Repo.MustOwner(), m.Repo, &repo_module.PushUpdateOptions{
+			notification.NotifySyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{
 				RefFullName: result.refName,
 				OldCommitID: git.EmptySHA,
 				NewCommitID: commitID,
 			}, repo_module.NewPushCommits())
-			notification.NotifySyncCreateRef(m.Repo.MustOwner(), m.Repo, tp, result.refName, commitID)
+			notification.NotifySyncCreateRef(ctx, m.Repo.MustOwner(ctx), m.Repo, tp, result.refName, commitID)
 			continue
 		}
 
 		// Delete reference
 		if result.newCommitID == gitShortEmptySha {
-			notification.NotifySyncDeleteRef(m.Repo.MustOwner(), m.Repo, tp, result.refName)
+			notification.NotifySyncDeleteRef(ctx, m.Repo.MustOwner(ctx), m.Repo, tp, result.refName)
 			continue
 		}
 
@@ -498,7 +498,7 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
 
 		theCommits.CompareURL = m.Repo.ComposeCompareURL(oldCommitID, newCommitID)
 
-		notification.NotifySyncPushCommits(m.Repo.MustOwner(), m.Repo, &repo_module.PushUpdateOptions{
+		notification.NotifySyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{
 			RefFullName: result.refName,
 			OldCommitID: oldCommitID,
 			NewCommitID: newCommitID,
diff --git a/services/packages/packages.go b/services/packages/packages.go
index 4513215ae..76fdd02bf 100644
--- a/services/packages/packages.go
+++ b/services/packages/packages.go
@@ -108,12 +108,12 @@ func createPackageAndAddFile(pvci *PackageCreationInfo, pfci *PackageFileCreatio
 	}
 
 	if created {
-		pd, err := packages_model.GetPackageDescriptor(ctx, pv)
+		pd, err := packages_model.GetPackageDescriptor(db.DefaultContext, pv)
 		if err != nil {
 			return nil, nil, err
 		}
 
-		notification.NotifyPackageCreate(pvci.Creator, pd)
+		notification.NotifyPackageCreate(db.DefaultContext, pvci.Creator, pd)
 	}
 
 	return pv, pf, nil
@@ -409,7 +409,7 @@ func RemovePackageVersion(doer *user_model.User, pv *packages_model.PackageVersi
 		return err
 	}
 
-	notification.NotifyPackageDelete(doer, pd)
+	notification.NotifyPackageDelete(db.DefaultContext, doer, pd)
 
 	return nil
 }
diff --git a/services/pull/check.go b/services/pull/check.go
index 6e91c22f3..faf3459f1 100644
--- a/services/pull/check.go
+++ b/services/pull/check.go
@@ -48,7 +48,7 @@ var (
 func AddToTaskQueue(pr *issues_model.PullRequest) {
 	err := prPatchCheckerQueue.PushFunc(strconv.FormatInt(pr.ID, 10), func() error {
 		pr.Status = issues_model.PullRequestStatusChecking
-		err := pr.UpdateColsIfNotMerged("status")
+		err := pr.UpdateColsIfNotMerged(db.DefaultContext, "status")
 		if err != nil {
 			log.Error("AddToTaskQueue.UpdateCols[%d].(add to queue): %v", pr.ID, err)
 		} else {
@@ -68,7 +68,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
 			return ErrHasMerged
 		}
 
-		if err := pr.LoadIssueCtx(ctx); err != nil {
+		if err := pr.LoadIssue(ctx); err != nil {
 			return err
 		} else if pr.Issue.IsClosed {
 			return ErrIsClosed
@@ -142,7 +142,7 @@ func isSignedIfRequired(ctx context.Context, pr *issues_model.PullRequest, doer
 
 // checkAndUpdateStatus checks if pull request is possible to leaving checking status,
 // and set to be either conflict or mergeable.
-func checkAndUpdateStatus(pr *issues_model.PullRequest) {
+func checkAndUpdateStatus(ctx context.Context, pr *issues_model.PullRequest) {
 	// Status is not changed to conflict means mergeable.
 	if pr.Status == issues_model.PullRequestStatusChecking {
 		pr.Status = issues_model.PullRequestStatusMergeable
@@ -155,7 +155,7 @@ func checkAndUpdateStatus(pr *issues_model.PullRequest) {
 	}
 
 	if !has {
-		if err := pr.UpdateColsIfNotMerged("merge_base", "status", "conflicted_files", "changed_protected_files"); err != nil {
+		if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files"); err != nil {
 			log.Error("Update[%d]: %v", pr.ID, err)
 		}
 	}
@@ -232,7 +232,7 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
 // manuallyMerged checks if a pull request got manually merged
 // When a pull request got manually merged mark the pull request as merged
 func manuallyMerged(ctx context.Context, pr *issues_model.PullRequest) bool {
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("PullRequest[%d].LoadBaseRepo: %v", pr.ID, err)
 		return false
 	}
@@ -278,7 +278,7 @@ func manuallyMerged(ctx context.Context, pr *issues_model.PullRequest) bool {
 			return false
 		}
 
-		notification.NotifyMergePullRequest(pr, merger)
+		notification.NotifyMergePullRequest(ctx, merger, pr)
 
 		log.Info("manuallyMerged[%d]: Marked as manually merged into %s/%s by commit id: %s", pr.ID, pr.BaseRepo.Name, pr.BaseBranch, commit.ID.String())
 		return true
@@ -346,7 +346,7 @@ func testPR(id int64) {
 		}
 		return
 	}
-	checkAndUpdateStatus(pr)
+	checkAndUpdateStatus(ctx, pr)
 }
 
 // CheckPrsForBaseBranch check all pulls with bseBrannch
diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go
index 5d846129f..10692221a 100644
--- a/services/pull/commit_status.go
+++ b/services/pull/commit_status.go
@@ -101,7 +101,7 @@ func IsPullCommitStatusPass(ctx context.Context, pr *issues_model.PullRequest) (
 // GetPullRequestCommitStatusState returns pull request merged commit status state
 func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullRequest) (structs.CommitStatusState, error) {
 	// Ensure HeadRepo is loaded
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		return "", errors.Wrap(err, "LoadHeadRepo")
 	}
 
@@ -129,7 +129,7 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR
 		return "", err
 	}
 
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		return "", errors.Wrap(err, "LoadBaseRepo")
 	}
 
diff --git a/services/pull/edits.go b/services/pull/edits.go
index 2938f2b10..84f7c80da 100644
--- a/services/pull/edits.go
+++ b/services/pull/edits.go
@@ -23,7 +23,7 @@ func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *issues_model.
 		return ErrUserHasNoPermissionForAction
 	}
 
-	if err := pr.LoadHeadRepo(); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		return err
 	}
 
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 6f37a887d..b29c9bc85 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -40,18 +40,18 @@ import (
 )
 
 // GetDefaultMergeMessage returns default message used when merging pull request
-func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) {
-	if err := pr.LoadHeadRepo(); err != nil {
+func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		return "", err
 	}
-	if err := pr.LoadBaseRepo(); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		return "", err
 	}
 	if pr.BaseRepo == nil {
 		return "", repo_model.ErrRepoNotExist{ID: pr.BaseRepoID}
 	}
 
-	if err := pr.LoadIssue(); err != nil {
+	if err := pr.LoadIssue(ctx); err != nil {
 		return "", err
 	}
 
@@ -90,7 +90,7 @@ func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *issues_model.PullRe
 				vars["HeadRepoOwnerName"] = pr.HeadRepo.OwnerName
 				vars["HeadRepoName"] = pr.HeadRepo.Name
 			}
-			refs, err := pr.ResolveCrossReferences(baseGitRepo.Ctx)
+			refs, err := pr.ResolveCrossReferences(ctx)
 			if err == nil {
 				closeIssueIndexes := make([]string, 0, len(refs))
 				closeWord := "close"
@@ -134,10 +134,10 @@ func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *issues_model.PullRe
 // Merge merges pull request to base repository.
 // Caller should check PR is ready to be merged (review and status checks)
 func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string, wasAutoMerged bool) error {
-	if err := pr.LoadHeadRepo(); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		log.Error("LoadHeadRepo: %v", err)
 		return fmt.Errorf("LoadHeadRepo: %w", err)
-	} else if err := pr.LoadBaseRepo(); err != nil {
+	} else if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("LoadBaseRepo: %v", err)
 		return fmt.Errorf("LoadBaseRepo: %w", err)
 	}
@@ -179,24 +179,24 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
 	pr.MergerID = doer.ID
 
 	if _, err := pr.SetMerged(hammerCtx); err != nil {
-		log.Error("setMerged [%d]: %v", pr.ID, err)
+		log.Error("SetMerged [%d]: %v", pr.ID, err)
 	}
 
-	if err := pr.LoadIssueCtx(hammerCtx); err != nil {
-		log.Error("loadIssue [%d]: %v", pr.ID, err)
+	if err := pr.LoadIssue(hammerCtx); err != nil {
+		log.Error("LoadIssue [%d]: %v", pr.ID, err)
 	}
 
 	if err := pr.Issue.LoadRepo(hammerCtx); err != nil {
-		log.Error("loadRepo for issue [%d]: %v", pr.ID, err)
+		log.Error("LoadRepo for issue [%d]: %v", pr.ID, err)
 	}
 	if err := pr.Issue.Repo.GetOwner(hammerCtx); err != nil {
-		log.Error("GetOwner for issue repo [%d]: %v", pr.ID, err)
+		log.Error("GetOwner for PR [%d]: %v", pr.ID, err)
 	}
 
 	if wasAutoMerged {
-		notification.NotifyAutoMergePullRequest(pr, doer)
+		notification.NotifyAutoMergePullRequest(hammerCtx, doer, pr)
 	} else {
-		notification.NotifyMergePullRequest(pr, doer)
+		notification.NotifyMergePullRequest(hammerCtx, doer, pr)
 	}
 
 	// Reset cached commit count
@@ -210,7 +210,7 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
 	}
 
 	for _, ref := range refs {
-		if err = ref.LoadIssueCtx(hammerCtx); err != nil {
+		if err = ref.LoadIssue(hammerCtx); err != nil {
 			return err
 		}
 		if err = ref.Issue.LoadRepo(hammerCtx); err != nil {
@@ -511,7 +511,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
 			return "", err
 		}
 
-		if err = pr.Issue.LoadPoster(); err != nil {
+		if err = pr.Issue.LoadPoster(ctx); err != nil {
 			log.Error("LoadPoster: %v", err)
 			return "", fmt.Errorf("LoadPoster: %w", err)
 		}
@@ -767,7 +767,7 @@ func IsUserAllowedToMerge(ctx context.Context, pr *issues_model.PullRequest, p a
 
 // CheckPullBranchProtections checks whether the PR is ready to be merged (reviews and status checks)
 func CheckPullBranchProtections(ctx context.Context, pr *issues_model.PullRequest, skipProtectedFilesCheck bool) (err error) {
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		return fmt.Errorf("LoadBaseRepo: %w", err)
 	}
 
@@ -878,7 +878,7 @@ func MergedManually(pr *issues_model.PullRequest, doer *user_model.User, baseGit
 		return err
 	}
 
-	notification.NotifyMergePullRequest(pr, doer)
+	notification.NotifyMergePullRequest(baseGitRepo.Ctx, doer, pr)
 	log.Info("manuallyMerged[%d]: Marked as manually merged into %s/%s by commit id: %s", pr.ID, pr.BaseRepo.Name, pr.BaseBranch, commitID)
 	return nil
 }
diff --git a/services/pull/patch.go b/services/pull/patch.go
index 9b87ac22e..1046095ff 100644
--- a/services/pull/patch.go
+++ b/services/pull/patch.go
@@ -30,7 +30,7 @@ import (
 
 // DownloadDiffOrPatch will write the patch for the pr to the writer
 func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io.Writer, patch, binary bool) error {
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("Unable to load base repository ID %d for pr #%d [%d]", pr.BaseRepoID, pr.Index, pr.ID)
 		return err
 	}
diff --git a/services/pull/pull.go b/services/pull/pull.go
index 5f8bd6b67..e0dcefe14 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -82,12 +82,12 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issu
 		return err
 	}
 
-	notification.NotifyNewPullRequest(pr, mentions)
+	notification.NotifyNewPullRequest(prCtx, pr, mentions)
 	if len(pull.Labels) > 0 {
-		notification.NotifyIssueChangeLabels(pull.Poster, pull, pull.Labels, nil)
+		notification.NotifyIssueChangeLabels(prCtx, pull.Poster, pull, pull.Labels, nil)
 	}
 	if pull.Milestone != nil {
-		notification.NotifyIssueChangeMilestone(pull.Poster, pull, 0)
+		notification.NotifyIssueChangeMilestone(prCtx, pull.Poster, pull, 0)
 	}
 
 	// add first push codes comment
@@ -172,7 +172,7 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer
 	}
 
 	// Check if pull request for the new target branch already exists
-	existingPr, err := issues_model.GetUnmergedPullRequest(pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, issues_model.PullRequestFlowGithub)
+	existingPr, err := issues_model.GetUnmergedPullRequest(ctx, pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, issues_model.PullRequestFlowGithub)
 	if existingPr != nil {
 		return issues_model.ErrPullRequestAlreadyExists{
 			ID:         existingPr.ID,
@@ -210,7 +210,7 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer
 	pr.CommitsAhead = divergence.Ahead
 	pr.CommitsBehind = divergence.Behind
 
-	if err := pr.UpdateColsIfNotMerged("merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil {
+	if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil {
 		return err
 	}
 
@@ -231,9 +231,9 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer
 }
 
 func checkForInvalidation(ctx context.Context, requests issues_model.PullRequestList, repoID int64, doer *user_model.User, branch string) error {
-	repo, err := repo_model.GetRepositoryByID(repoID)
+	repo, err := repo_model.GetRepositoryByIDCtx(ctx, repoID)
 	if err != nil {
-		return fmt.Errorf("GetRepositoryByID: %w", err)
+		return fmt.Errorf("GetRepositoryByIDCtx: %w", err)
 	}
 	gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
 	if err != nil {
@@ -301,7 +301,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
 					}
 
 					pr.Issue.PullRequest = pr
-					notification.NotifyPullRequestSynchronized(doer, pr)
+					notification.NotifyPullRequestSynchronized(ctx, doer, pr)
 				}
 			}
 		}
@@ -320,7 +320,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
 			AddToTaskQueue(pr)
 			comment, err := issues_model.CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID)
 			if err == nil && comment != nil {
-				notification.NotifyPullRequestPushCommits(doer, pr, comment)
+				notification.NotifyPullRequestPushCommits(ctx, doer, pr, comment)
 			}
 		}
 
@@ -352,14 +352,14 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
 // checkIfPRContentChanged checks if diff to target branch has changed by push
 // A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged
 func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) {
-	if err = pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err = pr.LoadHeadRepo(ctx); err != nil {
 		return false, fmt.Errorf("LoadHeadRepo: %w", err)
 	} else if pr.HeadRepo == nil {
 		// corrupt data assumed changed
 		return true, nil
 	}
 
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		return false, fmt.Errorf("LoadBaseRepo: %w", err)
 	}
 
@@ -430,22 +430,22 @@ func PushToBaseRepo(ctx context.Context, pr *issues_model.PullRequest) (err erro
 func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, prefixHeadBranch string) (err error) {
 	log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName())
 
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		log.Error("Unable to load head repository for PR[%d] Error: %v", pr.ID, err)
 		return err
 	}
 	headRepoPath := pr.HeadRepo.RepoPath()
 
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("Unable to load base repository for PR[%d] Error: %v", pr.ID, err)
 		return err
 	}
 	baseRepoPath := pr.BaseRepo.RepoPath()
 
-	if err = pr.LoadIssue(); err != nil {
+	if err = pr.LoadIssue(ctx); err != nil {
 		return fmt.Errorf("unable to load issue %d for pr %d: %w", pr.IssueID, pr.ID, err)
 	}
-	if err = pr.Issue.LoadPoster(); err != nil {
+	if err = pr.Issue.LoadPoster(ctx); err != nil {
 		return fmt.Errorf("unable to load poster %d for pr %d: %w", pr.Issue.PosterID, pr.ID, err)
 	}
 
@@ -485,7 +485,7 @@ func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, pre
 // UpdateRef update refs/pull/id/head directly for agit flow pull request
 func UpdateRef(ctx context.Context, pr *issues_model.PullRequest) (err error) {
 	log.Trace("UpdateRef[%d]: upgate pull request ref in base repo '%s'", pr.ID, pr.GetGitRefName())
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("Unable to load base repository for PR[%d] Error: %v", pr.ID, err)
 		return err
 	}
@@ -583,21 +583,21 @@ var commitMessageTrailersPattern = regexp.MustCompile(`(?:^|\n\n)(?:[\w-]+[ \t]*
 
 // GetSquashMergeCommitMessages returns the commit messages between head and merge base (if there is one)
 func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequest) string {
-	if err := pr.LoadIssue(); err != nil {
+	if err := pr.LoadIssue(ctx); err != nil {
 		log.Error("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err)
 		return ""
 	}
 
-	if err := pr.Issue.LoadPoster(); err != nil {
+	if err := pr.Issue.LoadPoster(ctx); err != nil {
 		log.Error("Cannot load poster %d for pr id %d, index %d Error: %v", pr.Issue.PosterID, pr.ID, pr.Index, err)
 		return ""
 	}
 
 	if pr.HeadRepo == nil {
 		var err error
-		pr.HeadRepo, err = repo_model.GetRepositoryByID(pr.HeadRepoID)
+		pr.HeadRepo, err = repo_model.GetRepositoryByIDCtx(ctx, pr.HeadRepoID)
 		if err != nil {
-			log.Error("GetRepositoryById[%d]: %v", pr.HeadRepoID, err)
+			log.Error("GetRepositoryByIdCtx[%d]: %v", pr.HeadRepoID, err)
 			return ""
 		}
 	}
@@ -743,10 +743,10 @@ func GetIssuesLastCommitStatus(ctx context.Context, issues issues_model.IssueLis
 
 // GetIssuesAllCommitStatus returns a map of issue ID to a list of all statuses for the most recent commit as well as a map of issue ID to only the commit's latest status
 func GetIssuesAllCommitStatus(ctx context.Context, issues issues_model.IssueList) (map[int64][]*git_model.CommitStatus, map[int64]*git_model.CommitStatus, error) {
-	if err := issues.LoadPullRequests(); err != nil {
+	if err := issues.LoadPullRequests(ctx); err != nil {
 		return nil, nil, err
 	}
-	if _, err := issues.LoadRepositories(); err != nil {
+	if _, err := issues.LoadRepositories(ctx); err != nil {
 		return nil, nil, err
 	}
 
@@ -802,7 +802,7 @@ func getAllCommitStatus(gitRepo *git.Repository, pr *issues_model.PullRequest) (
 // IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
 func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, branchName string) (bool, error) {
 	var err error
-	if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err = pr.LoadBaseRepo(ctx); err != nil {
 		return false, err
 	}
 	baseGitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath())
@@ -816,7 +816,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, br
 		return false, err
 	}
 
-	if err = pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err = pr.LoadHeadRepo(ctx); err != nil {
 		return false, err
 	}
 	var headGitRepo *git.Repository
diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go
index 769e3c72e..22eefd162 100644
--- a/services/pull/pull_test.go
+++ b/services/pull/pull_test.go
@@ -8,6 +8,7 @@ package pull
 import (
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unit"
@@ -40,18 +41,18 @@ func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
 
-	assert.NoError(t, pr.LoadBaseRepo())
+	assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
 	gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath())
 	assert.NoError(t, err)
 	defer gitRepo.Close()
 
-	mergeMessage, err := GetDefaultMergeMessage(gitRepo, pr, "")
+	mergeMessage, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "")
 	assert.NoError(t, err)
 	assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", mergeMessage)
 
 	pr.BaseRepoID = 1
 	pr.HeadRepoID = 2
-	mergeMessage, err = GetDefaultMergeMessage(gitRepo, pr, "")
+	mergeMessage, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "")
 	assert.NoError(t, err)
 	assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo1:branch2 into master", mergeMessage)
 }
@@ -70,12 +71,12 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
 
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo})
 
-	assert.NoError(t, pr.LoadBaseRepo())
+	assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
 	gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath())
 	assert.NoError(t, err)
 	defer gitRepo.Close()
 
-	mergeMessage, err := GetDefaultMergeMessage(gitRepo, pr, "")
+	mergeMessage, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "")
 	assert.NoError(t, err)
 
 	assert.Equal(t, "Merge pull request 'issue3' (!3) from branch2 into master", mergeMessage)
@@ -84,7 +85,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
 	pr.HeadRepoID = 2
 	pr.BaseRepo = nil
 	pr.HeadRepo = nil
-	mergeMessage, err = GetDefaultMergeMessage(gitRepo, pr, "")
+	mergeMessage, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "")
 	assert.NoError(t, err)
 
 	assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo2:branch2 into master", mergeMessage)
diff --git a/services/pull/review.go b/services/pull/review.go
index 16c9e108e..2555e1b3b 100644
--- a/services/pull/review.go
+++ b/services/pull/review.go
@@ -67,7 +67,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
 			return nil, err
 		}
 
-		notification.NotifyCreateIssueComment(doer, issue.Repo, issue, comment, mentions)
+		notification.NotifyCreateIssueComment(ctx, doer, issue.Repo, issue, comment, mentions)
 
 		return comment, nil
 	}
@@ -119,12 +119,12 @@ var notEnoughLines = regexp.MustCompile(`exit status 128 - fatal: file .* has on
 // createCodeComment creates a plain code comment at the specified line / path
 func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, treePath string, line, reviewID int64) (*issues_model.Comment, error) {
 	var commitID, patch string
-	if err := issue.LoadPullRequest(); err != nil {
-		return nil, fmt.Errorf("GetPullRequestByIssueID: %w", err)
+	if err := issue.LoadPullRequest(ctx); err != nil {
+		return nil, fmt.Errorf("LoadPullRequest: %w", err)
 	}
 	pr := issue.PullRequest
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
-		return nil, fmt.Errorf("LoadHeadRepo: %w", err)
+	if err := pr.LoadBaseRepo(ctx); err != nil {
+		return nil, fmt.Errorf("LoadBaseRepo: %w", err)
 	}
 	gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath())
 	if err != nil {
@@ -254,7 +254,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos
 		return nil, nil, err
 	}
 
-	notification.NotifyPullRequestReview(pr, review, comm, mentions)
+	notification.NotifyPullRequestReview(ctx, pr, review, comm, mentions)
 
 	for _, lines := range review.CodeComments {
 		for _, comments := range lines {
@@ -263,7 +263,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos
 				if err != nil {
 					return nil, nil, err
 				}
-				notification.NotifyPullRequestCodeComment(pr, codeComment, mentions)
+				notification.NotifyPullRequestCodeComment(ctx, pr, codeComment, mentions)
 			}
 		}
 	}
@@ -316,7 +316,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string,
 		return nil, nil
 	}
 
-	if err = review.Issue.LoadPullRequest(); err != nil {
+	if err = review.Issue.LoadPullRequest(ctx); err != nil {
 		return
 	}
 	if err = review.Issue.LoadAttributes(ctx); err != nil {
@@ -339,7 +339,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string,
 	comment.Poster = doer
 	comment.Issue = review.Issue
 
-	notification.NotifyPullRevieweDismiss(doer, review, comment)
+	notification.NotifyPullReviewDismiss(ctx, doer, review, comment)
 
 	return comment, err
 }
diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go
index 15e776c4b..9c04aa1c9 100644
--- a/services/pull/temp_repo.go
+++ b/services/pull/temp_repo.go
@@ -23,7 +23,7 @@ import (
 // createTemporaryRepo creates a temporary repo with "base" for pr.BaseBranch and "tracking" for  pr.HeadBranch
 // it also create a second base branch called "original_base"
 func createTemporaryRepo(ctx context.Context, pr *issues_model.PullRequest) (string, error) {
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		log.Error("LoadHeadRepo: %v", err)
 		return "", fmt.Errorf("LoadHeadRepo: %w", err)
 	} else if pr.HeadRepo == nil {
@@ -31,7 +31,7 @@ func createTemporaryRepo(ctx context.Context, pr *issues_model.PullRequest) (str
 		return "", &repo_model.ErrRepoNotExist{
 			ID: pr.HeadRepoID,
 		}
-	} else if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	} else if err := pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("LoadBaseRepo: %v", err)
 		return "", fmt.Errorf("LoadBaseRepo: %w", err)
 	} else if pr.BaseRepo == nil {
diff --git a/services/pull/update.go b/services/pull/update.go
index bd4880a2f..36e66bb7a 100644
--- a/services/pull/update.go
+++ b/services/pull/update.go
@@ -48,10 +48,10 @@ func Update(ctx context.Context, pull *issues_model.PullRequest, doer *user_mode
 		return fmt.Errorf("Not support update agit flow pull request's head branch")
 	}
 
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		log.Error("LoadHeadRepo: %v", err)
 		return fmt.Errorf("LoadHeadRepo: %w", err)
-	} else if err = pr.LoadBaseRepoCtx(ctx); err != nil {
+	} else if err = pr.LoadBaseRepo(ctx); err != nil {
 		log.Error("LoadBaseRepo: %v", err)
 		return fmt.Errorf("LoadBaseRepo: %w", err)
 	}
@@ -145,10 +145,10 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest,
 // GetDiverging determines how many commits a PR is ahead or behind the PR base branch
 func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*git.DivergeObject, error) {
 	log.Trace("GetDiverging[%d]: compare commits", pr.ID)
-	if err := pr.LoadBaseRepoCtx(ctx); err != nil {
+	if err := pr.LoadBaseRepo(ctx); err != nil {
 		return nil, err
 	}
-	if err := pr.LoadHeadRepoCtx(ctx); err != nil {
+	if err := pr.LoadHeadRepo(ctx); err != nil {
 		return nil, err
 	}
 
diff --git a/services/release/release.go b/services/release/release.go
index cf398debb..eb989381f 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -24,24 +24,24 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 )
 
-func createTag(gitRepo *git.Repository, rel *repo_model.Release, msg string) (bool, error) {
+func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Release, msg string) (bool, error) {
 	var created bool
 	// Only actual create when publish.
 	if !rel.IsDraft {
 		if !gitRepo.IsTagExist(rel.TagName) {
-			if err := rel.LoadAttributes(); err != nil {
+			if err := rel.LoadAttributes(ctx); err != nil {
 				log.Error("LoadAttributes: %v", err)
 				return false, err
 			}
 
-			protectedTags, err := git_model.GetProtectedTags(rel.Repo.ID)
+			protectedTags, err := git_model.GetProtectedTags(ctx, rel.Repo.ID)
 			if err != nil {
 				return false, fmt.Errorf("GetProtectedTags: %w", err)
 			}
 
 			// Trim '--' prefix to prevent command line argument vulnerability.
 			rel.TagName = strings.TrimPrefix(rel.TagName, "--")
-			isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, rel.TagName, rel.PublisherID)
+			isAllowed, err := git_model.IsUserAllowedToControlTag(ctx, protectedTags, rel.TagName, rel.PublisherID)
 			if err != nil {
 				return false, err
 			}
@@ -81,13 +81,13 @@ func createTag(gitRepo *git.Repository, rel *repo_model.Release, msg string) (bo
 			commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String())
 
 			notification.NotifyPushCommits(
-				rel.Publisher, rel.Repo,
+				ctx, rel.Publisher, rel.Repo,
 				&repository.PushUpdateOptions{
 					RefFullName: git.TagPrefix + rel.TagName,
 					OldCommitID: git.EmptySHA,
 					NewCommitID: commit.ID.String(),
 				}, commits)
-			notification.NotifyCreateRef(rel.Publisher, rel.Repo, "tag", git.TagPrefix+rel.TagName, commit.ID.String())
+			notification.NotifyCreateRef(ctx, rel.Publisher, rel.Repo, "tag", git.TagPrefix+rel.TagName, commit.ID.String())
 			rel.CreatedUnix = timeutil.TimeStampNow()
 		}
 		commit, err := gitRepo.GetTagCommit(rel.TagName)
@@ -102,7 +102,7 @@ func createTag(gitRepo *git.Repository, rel *repo_model.Release, msg string) (bo
 		}
 
 		if rel.PublisherID <= 0 {
-			u, err := user_model.GetUserByEmail(commit.Author.Email)
+			u, err := user_model.GetUserByEmailContext(ctx, commit.Author.Email)
 			if err == nil {
 				rel.PublisherID = u.ID
 			}
@@ -124,7 +124,7 @@ func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, attachmentU
 		}
 	}
 
-	if _, err = createTag(gitRepo, rel, msg); err != nil {
+	if _, err = createTag(gitRepo.Ctx, gitRepo, rel, msg); err != nil {
 		return err
 	}
 
@@ -138,7 +138,7 @@ func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, attachmentU
 	}
 
 	if !rel.IsDraft {
-		notification.NotifyNewRelease(rel)
+		notification.NotifyNewRelease(gitRepo.Ctx, rel)
 	}
 
 	return nil
@@ -173,7 +173,7 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R
 		IsTag:        true,
 	}
 
-	if _, err = createTag(gitRepo, rel, msg); err != nil {
+	if _, err = createTag(ctx, gitRepo, rel, msg); err != nil {
 		return err
 	}
 
@@ -190,7 +190,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod
 	if rel.ID == 0 {
 		return errors.New("UpdateRelease only accepts an exist release")
 	}
-	isCreated, err := createTag(gitRepo, rel, "")
+	isCreated, err := createTag(gitRepo.Ctx, gitRepo, rel, "")
 	if err != nil {
 		return err
 	}
@@ -272,12 +272,12 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod
 	}
 
 	if !isCreated {
-		notification.NotifyUpdateRelease(doer, rel)
+		notification.NotifyUpdateRelease(gitRepo.Ctx, doer, rel)
 		return
 	}
 
 	if !rel.IsDraft {
-		notification.NotifyNewRelease(rel)
+		notification.NotifyNewRelease(gitRepo.Ctx, rel)
 	}
 
 	return err
@@ -296,11 +296,11 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del
 	}
 
 	if delTag {
-		protectedTags, err := git_model.GetProtectedTags(rel.RepoID)
+		protectedTags, err := git_model.GetProtectedTags(ctx, rel.RepoID)
 		if err != nil {
 			return fmt.Errorf("GetProtectedTags: %w", err)
 		}
-		isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, rel.TagName, rel.PublisherID)
+		isAllowed, err := git_model.IsUserAllowedToControlTag(ctx, protectedTags, rel.TagName, rel.PublisherID)
 		if err != nil {
 			return err
 		}
@@ -318,15 +318,15 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del
 		}
 
 		notification.NotifyPushCommits(
-			doer, repo,
+			ctx, doer, repo,
 			&repository.PushUpdateOptions{
 				RefFullName: git.TagPrefix + rel.TagName,
 				OldCommitID: rel.Sha1,
 				NewCommitID: git.EmptySHA,
 			}, repository.NewPushCommits())
-		notification.NotifyDeleteRef(doer, repo, "tag", git.TagPrefix+rel.TagName)
+		notification.NotifyDeleteRef(ctx, doer, repo, "tag", git.TagPrefix+rel.TagName)
 
-		if err := repo_model.DeleteReleaseByID(id); err != nil {
+		if err := repo_model.DeleteReleaseByID(ctx, id); err != nil {
 			return fmt.Errorf("DeleteReleaseByID: %w", err)
 		}
 	} else {
@@ -338,11 +338,11 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del
 	}
 
 	rel.Repo = repo
-	if err = rel.LoadAttributes(); err != nil {
+	if err = rel.LoadAttributes(ctx); err != nil {
 		return fmt.Errorf("LoadAttributes: %w", err)
 	}
 
-	if err := repo_model.DeleteAttachmentsByRelease(rel.ID); err != nil {
+	if err := repo_model.DeleteAttachmentsByRelease(ctx, rel.ID); err != nil {
 		return fmt.Errorf("DeleteAttachments: %w", err)
 	}
 
@@ -353,7 +353,7 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del
 		}
 	}
 
-	notification.NotifyDeleteRelease(doer, rel)
+	notification.NotifyDeleteRelease(ctx, doer, rel)
 
 	return nil
 }
diff --git a/services/release/release_test.go b/services/release/release_test.go
index c0cafb5fc..1ade9bed3 100644
--- a/services/release/release_test.go
+++ b/services/release/release_test.go
@@ -297,13 +297,13 @@ func TestRelease_createTag(t *testing.T) {
 		IsPrerelease: false,
 		IsTag:        false,
 	}
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	assert.NotEmpty(t, release.CreatedUnix)
 	releaseCreatedUnix := release.CreatedUnix
 	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 	release.Note = "Changed note"
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 
@@ -321,12 +321,12 @@ func TestRelease_createTag(t *testing.T) {
 		IsPrerelease: false,
 		IsTag:        false,
 	}
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	releaseCreatedUnix = release.CreatedUnix
 	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 	release.Title = "Changed title"
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 
@@ -344,13 +344,13 @@ func TestRelease_createTag(t *testing.T) {
 		IsPrerelease: true,
 		IsTag:        false,
 	}
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	releaseCreatedUnix = release.CreatedUnix
 	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 	release.Title = "Changed title"
 	release.Note = "Changed note"
-	_, err = createTag(gitRepo, release, "")
+	_, err = createTag(db.DefaultContext, gitRepo, release, "")
 	assert.NoError(t, err)
 	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 }
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index 57a21f500..3895c54c7 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -96,7 +96,7 @@ func AdoptRepository(doer, u *user_model.User, opts repo_module.CreateRepoOption
 		return nil, err
 	}
 
-	notification.NotifyCreateRepository(doer, u, repo)
+	notification.NotifyCreateRepository(db.DefaultContext, doer, u, repo)
 
 	return repo, nil
 }
diff --git a/services/repository/branch.go b/services/repository/branch.go
index 132842258..e1f26b89a 100644
--- a/services/repository/branch.go
+++ b/services/repository/branch.go
@@ -11,6 +11,7 @@ import (
 	"strings"
 
 	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/models/db"
 	git_model "code.gitea.io/gitea/models/git"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
@@ -141,8 +142,8 @@ func RenameBranch(repo *repo_model.Repository, doer *user_model.User, gitRepo *g
 		return "", err
 	}
 
-	notification.NotifyDeleteRef(doer, repo, "branch", git.BranchPrefix+from)
-	notification.NotifyCreateRef(doer, repo, "branch", git.BranchPrefix+to, refID)
+	notification.NotifyDeleteRef(db.DefaultContext, doer, repo, "branch", git.BranchPrefix+from)
+	notification.NotifyCreateRef(db.DefaultContext, doer, repo, "branch", git.BranchPrefix+to, refID)
 
 	return "", nil
 }
diff --git a/services/repository/fork.go b/services/repository/fork.go
index e597bfa44..a9a2b33ed 100644
--- a/services/repository/fork.go
+++ b/services/repository/fork.go
@@ -177,7 +177,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 		}
 	}
 
-	notification.NotifyForkRepository(doer, opts.BaseRepo, repo)
+	notification.NotifyForkRepository(ctx, doer, opts.BaseRepo, repo)
 
 	return repo, nil
 }
diff --git a/services/repository/push.go b/services/repository/push.go
index 6776ff9f7..e2db18e1f 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -117,7 +117,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 			tagName := opts.TagName()
 			if opts.IsDelRef() {
 				notification.NotifyPushCommits(
-					pusher, repo,
+					db.DefaultContext, pusher, repo,
 					&repo_module.PushUpdateOptions{
 						RefFullName: git.TagPrefix + tagName,
 						OldCommitID: opts.OldCommitID,
@@ -125,7 +125,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 					}, repo_module.NewPushCommits())
 
 				delTags = append(delTags, tagName)
-				notification.NotifyDeleteRef(pusher, repo, "tag", opts.RefFullName)
+				notification.NotifyDeleteRef(db.DefaultContext, pusher, repo, "tag", opts.RefFullName)
 			} else { // is new tag
 				newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
 				if err != nil {
@@ -137,7 +137,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 				commits.CompareURL = repo.ComposeCompareURL(git.EmptySHA, opts.NewCommitID)
 
 				notification.NotifyPushCommits(
-					pusher, repo,
+					db.DefaultContext, pusher, repo,
 					&repo_module.PushUpdateOptions{
 						RefFullName: git.TagPrefix + tagName,
 						OldCommitID: git.EmptySHA,
@@ -145,7 +145,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 					}, commits)
 
 				addTags = append(addTags, tagName)
-				notification.NotifyCreateRef(pusher, repo, "tag", opts.RefFullName, opts.NewCommitID)
+				notification.NotifyCreateRef(db.DefaultContext, pusher, repo, "tag", opts.RefFullName, opts.NewCommitID)
 			}
 		} else if opts.IsBranch() { // If is branch reference
 			if pusher == nil || pusher.ID != opts.PusherID {
@@ -190,7 +190,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 					if err != nil {
 						return fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err)
 					}
-					notification.NotifyCreateRef(pusher, repo, "branch", opts.RefFullName, opts.NewCommitID)
+					notification.NotifyCreateRef(db.DefaultContext, pusher, repo, "branch", opts.RefFullName, opts.NewCommitID)
 				} else {
 					l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
 					if err != nil {
@@ -250,7 +250,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 					commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
 				}
 
-				notification.NotifyPushCommits(pusher, repo, opts, commits)
+				notification.NotifyPushCommits(db.DefaultContext, pusher, repo, opts, commits)
 
 				if err = git_model.RemoveDeletedBranchByName(repo.ID, branch); err != nil {
 					log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err)
@@ -261,7 +261,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 					log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err)
 				}
 			} else {
-				notification.NotifyDeleteRef(pusher, repo, "branch", opts.RefFullName)
+				notification.NotifyDeleteRef(db.DefaultContext, pusher, repo, "branch", opts.RefFullName)
 				if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil {
 					// close all related pulls
 					log.Error("close related pull request failed: %v", err)
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 2f2c27ff2..c369b98aa 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -32,7 +32,7 @@ func CreateRepository(doer, owner *user_model.User, opts repo_module.CreateRepoO
 		return nil, err
 	}
 
-	notification.NotifyCreateRepository(doer, owner, repo)
+	notification.NotifyCreateRepository(db.DefaultContext, doer, owner, repo)
 
 	return repo, nil
 }
@@ -45,7 +45,7 @@ func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_mod
 
 	if notify {
 		// If the repo itself has webhooks, we need to trigger them before deleting it...
-		notification.NotifyDeleteRepository(doer, repo)
+		notification.NotifyDeleteRepository(ctx, doer, repo)
 	}
 
 	if err := models.DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil {
diff --git a/services/repository/template.go b/services/repository/template.go
index bb5e3f466..625bc305d 100644
--- a/services/repository/template.go
+++ b/services/repository/template.go
@@ -101,7 +101,7 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R
 		return nil, err
 	}
 
-	notification.NotifyCreateRepository(doer, owner, generateRepo)
+	notification.NotifyCreateRepository(db.DefaultContext, doer, owner, generateRepo)
 
 	return generateRepo, nil
 }
diff --git a/services/repository/transfer.go b/services/repository/transfer.go
index a0f4a7685..2778f2e74 100644
--- a/services/repository/transfer.go
+++ b/services/repository/transfer.go
@@ -55,7 +55,7 @@ func TransferOwnership(doer, newOwner *user_model.User, repo *repo_model.Reposit
 		}
 	}
 
-	notification.NotifyTransferRepository(doer, repo, oldOwner.Name)
+	notification.NotifyTransferRepository(db.DefaultContext, doer, repo, oldOwner.Name)
 
 	return nil
 }
@@ -78,7 +78,7 @@ func ChangeRepositoryName(doer *user_model.User, repo *repo_model.Repository, ne
 	repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
 
 	repo.Name = newRepoName
-	notification.NotifyRenameRepository(doer, repo, oldRepoName)
+	notification.NotifyRenameRepository(db.DefaultContext, doer, repo, oldRepoName)
 
 	return nil
 }
@@ -127,7 +127,7 @@ func StartRepositoryTransfer(doer, newOwner *user_model.User, repo *repo_model.R
 	}
 
 	// notify users who are able to accept / reject transfer
-	notification.NotifyRepoPendingTransfer(doer, newOwner, repo)
+	notification.NotifyRepoPendingTransfer(db.DefaultContext, doer, newOwner, repo)
 
 	return nil
 }
diff --git a/services/task/migrate.go b/services/task/migrate.go
index faca6908a..307c60a09 100644
--- a/services/task/migrate.go
+++ b/services/task/migrate.go
@@ -51,7 +51,7 @@ func runMigrateTask(t *admin_model.Task) (err error) {
 		if err == nil {
 			err = admin_model.FinishMigrateTask(t)
 			if err == nil {
-				notification.NotifyMigrateRepository(t.Doer, t.Owner, t.Repo)
+				notification.NotifyMigrateRepository(db.DefaultContext, t.Doer, t.Owner, t.Repo)
 				return
 			}
 
diff --git a/services/user/user.go b/services/user/user.go
index 4186efe68..9976bc7bd 100644
--- a/services/user/user.go
+++ b/services/user/user.go
@@ -78,7 +78,7 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
 				Actor:   u,
 			})
 			if err != nil {
-				return fmt.Errorf("SearchRepositoryByName: %w", err)
+				return fmt.Errorf("GetUserRepositories: %w", err)
 			}
 			if len(repos) == 0 {
 				break
diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go
index 342e764f4..1780022eb 100644
--- a/services/webhook/webhook.go
+++ b/services/webhook/webhook.go
@@ -224,7 +224,7 @@ func PrepareWebhooks(ctx context.Context, source EventSource, event webhook_mode
 		}
 		ws = append(ws, repoHooks...)
 
-		owner = source.Repository.MustOwner()
+		owner = source.Repository.MustOwner(ctx)
 	}
 
 	// check if owner is an org and append additional webhooks
diff --git a/templates/user/notification/notification_div.tmpl b/templates/user/notification/notification_div.tmpl
index 192652d06..18071549a 100644
--- a/templates/user/notification/notification_div.tmpl
+++ b/templates/user/notification/notification_div.tmpl
@@ -34,7 +34,6 @@
 						{{range $notification := .Notifications}}
 							{{$issue := .Issue}}
 							{{$repo := .Repository}}
-							{{$repoOwner := $repo.MustOwner}}
 							<tr id="notification_{{.ID}}">
 								<td class="collapsing" data-href="{{.HTMLURL}}">
 									{{if eq .Status 3}}
@@ -69,9 +68,7 @@
 									</a>
 								</td>
 								<td data-href="{{$repo.Link}}">
-									<a class="item" href="{{$repo.Link}}">
-										{{$repoOwner.Name}}/{{$repo.Name}}
-									</a>
+									<a class="item" href="{{$repo.Link}}">{{$repo.FullName}}</a>
 								</td>
 								<td class="collapsing">
 									{{if ne .Status 3}}
diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go
index 126d88684..9cac32b9b 100644
--- a/tests/integration/api_comment_test.go
+++ b/tests/integration/api_comment_test.go
@@ -10,6 +10,7 @@ import (
 	"net/url"
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
@@ -115,7 +116,7 @@ func TestAPIGetComment(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 
 	comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
-	assert.NoError(t, comment.LoadIssue())
+	assert.NoError(t, comment.LoadIssue(db.DefaultContext))
 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID})
 	repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
 
@@ -129,7 +130,7 @@ func TestAPIGetComment(t *testing.T) {
 	var apiComment api.Comment
 	DecodeJSON(t, resp, &apiComment)
 
-	assert.NoError(t, comment.LoadPoster())
+	assert.NoError(t, comment.LoadPoster(db.DefaultContext))
 	expect := convert.ToComment(comment)
 
 	assert.Equal(t, expect.ID, apiComment.ID)
diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go
index a3cb9303f..9afc7475e 100644
--- a/tests/integration/api_issue_reaction_test.go
+++ b/tests/integration/api_issue_reaction_test.go
@@ -82,7 +82,7 @@ func TestAPICommentReactions(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 
 	comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
-	_ = comment.LoadIssue()
+	_ = comment.LoadIssue(db.DefaultContext)
 	issue := comment.Issue
 	_ = issue.LoadRepo(db.DefaultContext)
 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
diff --git a/tests/integration/api_notification_test.go b/tests/integration/api_notification_test.go
index bf85520bb..f14380222 100644
--- a/tests/integration/api_notification_test.go
+++ b/tests/integration/api_notification_test.go
@@ -10,6 +10,7 @@ import (
 	"testing"
 
 	activities_model "code.gitea.io/gitea/models/activities"
+	"code.gitea.io/gitea/models/db"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
@@ -25,7 +26,7 @@ func TestAPINotification(t *testing.T) {
 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
-	assert.NoError(t, thread5.LoadAttributes())
+	assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
 	session := loginUser(t, user2.Name)
 	token := getTokenForLoggedInUser(t, session)
 
@@ -143,7 +144,7 @@ func TestAPINotificationPUT(t *testing.T) {
 
 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
-	assert.NoError(t, thread5.LoadAttributes())
+	assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
 	session := loginUser(t, user2.Name)
 	token := getTokenForLoggedInUser(t, session)
 
diff --git a/tests/integration/api_pull_commits_test.go b/tests/integration/api_pull_commits_test.go
index aa58f44bb..6753ceaa9 100644
--- a/tests/integration/api_pull_commits_test.go
+++ b/tests/integration/api_pull_commits_test.go
@@ -8,6 +8,7 @@ import (
 	"net/http"
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
@@ -19,12 +20,12 @@ import (
 
 func TestAPIPullCommits(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
-	pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
-	assert.NoError(t, pullIssue.LoadIssue())
-	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID})
+	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
+	assert.NoError(t, pr.LoadIssue(db.DefaultContext))
+	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pr.HeadRepoID})
 
 	session := loginUser(t, "user2")
-	req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/commits", repo.OwnerName, repo.Name, pullIssue.Index)
+	req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/commits", repo.OwnerName, repo.Name, pr.Index)
 	resp := session.MakeRequest(t, req, http.StatusOK)
 
 	var commits []*api.Commit
diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go
index 8ce92f3d4..81842b05f 100644
--- a/tests/integration/api_pull_test.go
+++ b/tests/integration/api_pull_test.go
@@ -10,6 +10,7 @@ import (
 	"net/http"
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
@@ -65,11 +66,11 @@ func TestAPIMergePullWIP(t *testing.T) {
 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
 	pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false))
-	pr.LoadIssue()
+	pr.LoadIssue(db.DefaultContext)
 	issue_service.ChangeTitle(pr.Issue, owner, setting.Repository.PullRequest.WorkInProgressPrefixes[0]+" "+pr.Issue.Title)
 
 	// force reload
-	pr.LoadAttributes()
+	pr.LoadAttributes(db.DefaultContext)
 
 	assert.Contains(t, pr.Issue.Title, setting.Repository.PullRequest.WorkInProgressPrefixes[0])
 
diff --git a/tests/integration/eventsource_test.go b/tests/integration/eventsource_test.go
index cd496e012..2f698659c 100644
--- a/tests/integration/eventsource_test.go
+++ b/tests/integration/eventsource_test.go
@@ -11,6 +11,7 @@ import (
 	"time"
 
 	activities_model "code.gitea.io/gitea/models/activities"
+	"code.gitea.io/gitea/models/db"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
@@ -57,7 +58,7 @@ func TestEventSourceManagerRun(t *testing.T) {
 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
-	assert.NoError(t, thread5.LoadAttributes())
+	assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
 	session := loginUser(t, user2.Name)
 	token := getTokenForLoggedInUser(t, session)
 
diff --git a/tests/integration/pull_update_test.go b/tests/integration/pull_update_test.go
index c08faaaeb..1bfe5c705 100644
--- a/tests/integration/pull_update_test.go
+++ b/tests/integration/pull_update_test.go
@@ -35,8 +35,8 @@ func TestAPIPullUpdate(t *testing.T) {
 		assert.NoError(t, err)
 		assert.EqualValues(t, 1, diffCount.Behind)
 		assert.EqualValues(t, 1, diffCount.Ahead)
-		assert.NoError(t, pr.LoadBaseRepo())
-		assert.NoError(t, pr.LoadIssue())
+		assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
+		assert.NoError(t, pr.LoadIssue(db.DefaultContext))
 
 		session := loginUser(t, "user2")
 		token := getTokenForLoggedInUser(t, session)
@@ -63,8 +63,8 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
 		assert.NoError(t, err)
 		assert.EqualValues(t, 1, diffCount.Behind)
 		assert.EqualValues(t, 1, diffCount.Ahead)
-		assert.NoError(t, pr.LoadBaseRepo())
-		assert.NoError(t, pr.LoadIssue())
+		assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
+		assert.NoError(t, pr.LoadIssue(db.DefaultContext))
 
 		session := loginUser(t, "user2")
 		token := getTokenForLoggedInUser(t, session)
diff --git a/tests/integration/repo_tag_test.go b/tests/integration/repo_tag_test.go
index fb08895e2..e20c72591 100644
--- a/tests/integration/repo_tag_test.go
+++ b/tests/integration/repo_tag_test.go
@@ -9,6 +9,7 @@ import (
 	"testing"
 
 	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/models/db"
 	git_model "code.gitea.io/gitea/models/git"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
@@ -74,22 +75,22 @@ func TestCreateNewTagProtected(t *testing.T) {
 	})
 
 	// Cleanup
-	releases, err := repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{
+	releases, err := repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{
 		IncludeTags: true,
 		TagNames:    []string{"v-1", "v-1.1"},
 	})
 	assert.NoError(t, err)
 
 	for _, release := range releases {
-		err = repo_model.DeleteReleaseByID(release.ID)
+		err = repo_model.DeleteReleaseByID(db.DefaultContext, release.ID)
 		assert.NoError(t, err)
 	}
 
-	protectedTags, err := git_model.GetProtectedTags(repo.ID)
+	protectedTags, err := git_model.GetProtectedTags(db.DefaultContext, repo.ID)
 	assert.NoError(t, err)
 
 	for _, protectedTag := range protectedTags {
-		err = git_model.DeleteProtectedTag(protectedTag)
+		err = git_model.DeleteProtectedTag(db.DefaultContext, protectedTag)
 		assert.NoError(t, err)
 	}
 }