From 67d90e7d55a9701aed92b1c6780e5a4d8ce6f004 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Thu, 18 Jun 2020 23:34:03 +0800
Subject: [PATCH 01/13] Decrease the  num_stars when deleting a repo

fix #11949

Signed-off-by: a1012112796 <1012112796@qq.com>
---
 models/repo.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/models/repo.go b/models/repo.go
index 3b874f3359af6..024467700031b 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -1586,6 +1586,10 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
 		releaseAttachments = append(releaseAttachments, attachments[i].LocalPath())
 	}
 
+	if _, err = sess.Exec("UPDATE `user` SET num_stars=num_stars-1 WHERE id IN (SELECT `uid` FROM `star` WHERE repo_id = ?)", repo.ID); err != nil {
+		return err
+	}
+
 	if err = deleteBeans(sess,
 		&Access{RepoID: repo.ID},
 		&Action{RepoID: repo.ID},

From 35daf9d39b200439eda51117db8e19fdc8ff832e Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Fri, 19 Jun 2020 01:18:45 +0800
Subject: [PATCH 02/13] Add migration

---
 models/migrations/migrations.go |  2 ++
 models/migrations/v143.go       | 38 +++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
 create mode 100644 models/migrations/v143.go

diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 6cc80249a3d42..d205794e1f346 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -218,6 +218,8 @@ var migrations = []Migration{
 	NewMigration("Add KeepActivityPrivate to User table", addKeepActivityPrivateUserColumn),
 	// v142 -> v143
 	NewMigration("Ensure Repository.IsArchived is not null", setIsArchivedToFalse),
+	// v143 -> v144
+	NewMigration("recalculate Stars number for all user", recalculateStars),
 }
 
 // GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v143.go b/models/migrations/v143.go
new file mode 100644
index 0000000000000..a5c349a1ad091
--- /dev/null
+++ b/models/migrations/v143.go
@@ -0,0 +1,38 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/log"
+	"xorm.io/xorm"
+)
+
+func recalculateStars(x *xorm.Engine) (err error) {
+	// because of issue https://github.com/go-gitea/gitea/issues/11949,
+	// recalculate Stars number for all users to fully fix it.
+
+	userIDs := make([]int64, 0)
+	err = x.SQL("SELECT id FROM `user` WHERE type = 0").Find(&userIDs)
+	if err != nil {
+		return
+	}
+
+	var number int64
+
+	for _, uid := range userIDs {
+		if number, err = x.Where("uid = ?", uid).Count(new(models.Star)); err != nil {
+			return
+		}
+
+		if _, err = x.Exec("UPDATE `user` SET num_stars=? WHERE id = ?", number, uid); err != nil {
+			return err
+		}
+	}
+
+	log.Debug("recalculate Stars number for all user finished")
+
+	return err
+}

From 737b9974abc7c73f0886b498e0b16e96f32b6d52 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Fri, 19 Jun 2020 12:01:50 +0800
Subject: [PATCH 03/13] use batch

---
 models/migrations/v143.go | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index a5c349a1ad091..bae465e1eaf0c 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -14,25 +14,33 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	// because of issue https://github.com/go-gitea/gitea/issues/11949,
 	// recalculate Stars number for all users to fully fix it.
 
-	userIDs := make([]int64, 0)
-	err = x.SQL("SELECT id FROM `user` WHERE type = 0").Find(&userIDs)
-	if err != nil {
-		return
-	}
-
-	var number int64
+	const batchSize = 100
+	sess := x.NewSession()
+	defer sess.Close()
 
-	for _, uid := range userIDs {
-		if number, err = x.Where("uid = ?", uid).Count(new(models.Star)); err != nil {
-			return
+	for start := 0; ; start += batchSize {
+		userIDs := make([]int64, 0, batchSize)
+		if err = sess.Table("user").Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&userIDs); err != nil {
+			return err
+		}
+		if len(userIDs) == 0 {
+			break
 		}
 
-		if _, err = x.Exec("UPDATE `user` SET num_stars=? WHERE id = ?", number, uid); err != nil {
-			return err
+		var number int64
+
+		for _, uid := range userIDs {
+			if number, err = x.Where("uid = ?", uid).Count(new(models.Star)); err != nil {
+				return
+			}
+
+			if _, err = x.Exec("UPDATE `user` SET num_stars=? WHERE id = ?", number, uid); err != nil {
+				return err
+			}
 		}
 	}
 
 	log.Debug("recalculate Stars number for all user finished")
 
-	return err
+	return sess.Commit()
 }

From 5bdfa3d160f33bb78604924145df08cfd2bd25b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E6=99=BA=E8=B6=85?= <1012112796@qq.com>
Date: Fri, 19 Jun 2020 21:47:57 +0800
Subject: [PATCH 04/13] Apply suggestions from code review

Co-authored-by: Lauris BH <lauris@nix.lv>
---
 models/migrations/v143.go | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index bae465e1eaf0c..c9ee8012b5f0d 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -7,6 +7,7 @@ package migrations
 import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/log"
+
 	"xorm.io/xorm"
 )
 
@@ -30,13 +31,10 @@ func recalculateStars(x *xorm.Engine) (err error) {
 		var number int64
 
 		for _, uid := range userIDs {
-			if number, err = x.Where("uid = ?", uid).Count(new(models.Star)); err != nil {
-				return
-			}
-
-			if _, err = x.Exec("UPDATE `user` SET num_stars=? WHERE id = ?", number, uid); err != nil {
+			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", uid, uid); err != nil {
 				return err
 			}
+			
 		}
 	}
 

From 9c1e588dbd2d256da5b3f61e6cbeffd285953fcf Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Fri, 19 Jun 2020 21:57:48 +0800
Subject: [PATCH 05/13] fix lint

---
 models/migrations/v143.go | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index c9ee8012b5f0d..01a85eccf594b 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -5,7 +5,6 @@
 package migrations
 
 import (
-	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/log"
 
 	"xorm.io/xorm"
@@ -34,7 +33,7 @@ func recalculateStars(x *xorm.Engine) (err error) {
 			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", uid, uid); err != nil {
 				return err
 			}
-			
+
 		}
 	}
 

From 8eaa0a6730809f9249452c0faa1cf580e5f50fb7 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Fri, 19 Jun 2020 22:04:02 +0800
Subject: [PATCH 06/13] fix lint

---
 models/migrations/v143.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 01a85eccf594b..aee523aaf882a 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -27,8 +27,6 @@ func recalculateStars(x *xorm.Engine) (err error) {
 			break
 		}
 
-		var number int64
-
 		for _, uid := range userIDs {
 			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", uid, uid); err != nil {
 				return err

From b1347b899860dd35af45ef59ba538eae4eab750b Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 20 Jun 2020 00:32:14 +0800
Subject: [PATCH 07/13] fix ci

---
 models/migrations/v143.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index aee523aaf882a..1c3a54acc84e3 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -20,7 +20,7 @@ func recalculateStars(x *xorm.Engine) (err error) {
 
 	for start := 0; ; start += batchSize {
 		userIDs := make([]int64, 0, batchSize)
-		if err = sess.Table("user").Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&userIDs); err != nil {
+		if err = sess.Table("`user`").Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&userIDs); err != nil {
 			return err
 		}
 		if len(userIDs) == 0 {

From 974c92612e0b573b2d93769542f21700619714c5 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 20 Jun 2020 00:52:15 +0800
Subject: [PATCH 08/13] fix ci2

---
 models/migrations/v143.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 1c3a54acc84e3..3f51f35d546e2 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -5,6 +5,7 @@
 package migrations
 
 import (
+	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/log"
 
 	"xorm.io/xorm"
@@ -19,19 +20,18 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	defer sess.Close()
 
 	for start := 0; ; start += batchSize {
-		userIDs := make([]int64, 0, batchSize)
-		if err = sess.Table("`user`").Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&userIDs); err != nil {
+		users := make([]models.User, 0, batchSize)
+		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
 			return err
 		}
-		if len(userIDs) == 0 {
+		if len(users) == 0 {
 			break
 		}
 
-		for _, uid := range userIDs {
-			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", uid, uid); err != nil {
+		for _, user := range users {
+			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
 				return err
 			}
-
 		}
 	}
 

From dc7f9b3be164a590c312dc5f34603281a23cc53a Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Fri, 26 Jun 2020 22:06:20 +0800
Subject: [PATCH 09/13] add doctor

---
 cmd/doctor.go             | 10 ++++++++++
 models/migrations/v143.go | 25 +------------------------
 models/repo.go            | 27 +++++++++++++++++++++++++++
 models/repo_test.go       |  6 ++++++
 4 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/cmd/doctor.go b/cmd/doctor.go
index 45a50c82660d4..48fd3158a49f4 100644
--- a/cmd/doctor.go
+++ b/cmd/doctor.go
@@ -120,6 +120,12 @@ var checklist = []check{
 		isDefault: false,
 		f:         runDoctorPRMergeBase,
 	},
+	{
+		title:     "Recalculate Stars number for all user",
+		name:      "recalculate_stars_number",
+		isDefault: false,
+		f:         runDoctorUserStarNum,
+	},
 	// more checks please append here
 }
 
@@ -494,6 +500,10 @@ func runDoctorPRMergeBase(ctx *cli.Context) ([]string, error) {
 	return results, err
 }
 
+func runDoctorUserStarNum(ctx *cli.Context) ([]string, error) {
+	return nil, models.DoctorUserStarNum()
+}
+
 func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
 	path, err := exec.LookPath(setting.ScriptType)
 	if err != nil {
diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 3f51f35d546e2..b711bb6575431 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -6,7 +6,6 @@ package migrations
 
 import (
 	"code.gitea.io/gitea/models"
-	"code.gitea.io/gitea/modules/log"
 
 	"xorm.io/xorm"
 )
@@ -15,27 +14,5 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	// because of issue https://github.com/go-gitea/gitea/issues/11949,
 	// recalculate Stars number for all users to fully fix it.
 
-	const batchSize = 100
-	sess := x.NewSession()
-	defer sess.Close()
-
-	for start := 0; ; start += batchSize {
-		users := make([]models.User, 0, batchSize)
-		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
-			return err
-		}
-		if len(users) == 0 {
-			break
-		}
-
-		for _, user := range users {
-			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
-				return err
-			}
-		}
-	}
-
-	log.Debug("recalculate Stars number for all user finished")
-
-	return sess.Commit()
+	return models.DoctorUserStarNum()
 }
diff --git a/models/repo.go b/models/repo.go
index 024467700031b..8509568bf731e 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -2355,3 +2355,30 @@ func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error {
 func UpdateRepositoryCols(repo *Repository, cols ...string) error {
 	return updateRepositoryCols(x, repo, cols...)
 }
+
+// DoctorUserStarNum recalculate Stars number for all user
+func DoctorUserStarNum() (err error) {
+	const batchSize = 100
+	sess := x.NewSession()
+	defer sess.Close()
+
+	for start := 0; ; start += batchSize {
+		users := make([]User, 0, batchSize)
+		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
+			return err
+		}
+		if len(users) == 0 {
+			break
+		}
+
+		for _, user := range users {
+			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
+				return err
+			}
+		}
+	}
+
+	log.Debug("recalculate Stars number for all user finished")
+
+	return sess.Commit()
+}
diff --git a/models/repo_test.go b/models/repo_test.go
index 20da43fbbfc91..045f94670bde0 100644
--- a/models/repo_test.go
+++ b/models/repo_test.go
@@ -187,3 +187,9 @@ func TestDeleteAvatar(t *testing.T) {
 
 	assert.Equal(t, "", repo.Avatar)
 }
+
+func TestDoctorUserStarNum(t *testing.T) {
+	assert.NoError(t, PrepareTestDatabase())
+
+	assert.NoError(t, DoctorUserStarNum())
+}

From b935dba37bbc9d878dfca15331ffcbb82849da7d Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 27 Jun 2020 09:08:43 +0800
Subject: [PATCH 10/13]  duplicate code

---
 models/migrations/v143.go | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index b711bb6575431..56996d3dde742 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -5,8 +5,7 @@
 package migrations
 
 import (
-	"code.gitea.io/gitea/models"
-
+	"code.gitea.io/gitea/modules/log"
 	"xorm.io/xorm"
 )
 
@@ -14,5 +13,27 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	// because of issue https://github.com/go-gitea/gitea/issues/11949,
 	// recalculate Stars number for all users to fully fix it.
 
-	return models.DoctorUserStarNum()
+	const batchSize = 100
+	sess := x.NewSession()
+	defer sess.Close()
+
+	for start := 0; ; start += batchSize {
+		users := make([]User, 0, batchSize)
+		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
+			return err
+		}
+		if len(users) == 0 {
+			break
+		}
+
+		for _, user := range users {
+			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
+				return err
+			}
+		}
+	}
+
+	log.Debug("recalculate Stars number for all user finished")
+
+	return sess.Commit()
 }

From 8b6f9b319ec679bfe2899eb55798eaadbe8187c4 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 27 Jun 2020 09:22:57 +0800
Subject: [PATCH 11/13] fix migration

---
 models/migrations/v143.go | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 56996d3dde742..4dc3ce3ec7261 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -6,6 +6,7 @@ package migrations
 
 import (
 	"code.gitea.io/gitea/modules/log"
+
 	"xorm.io/xorm"
 )
 
@@ -13,6 +14,14 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	// because of issue https://github.com/go-gitea/gitea/issues/11949,
 	// recalculate Stars number for all users to fully fix it.
 
+	// UserType defines the user type
+	type UserType int
+
+	type User struct {
+		ID   int64 `xorm:"pk autoincr"`
+		Type UserType
+	}
+
 	const batchSize = 100
 	sess := x.NewSession()
 	defer sess.Close()

From 7b7232a43413aa61760206ec6c3250baa11f60d3 Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 27 Jun 2020 21:32:04 +0800
Subject: [PATCH 12/13] fix some nits

---
 models/migrations/v143.go | 18 +++++++++---------
 models/repo.go            | 12 ++++++++----
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 4dc3ce3ec7261..8f53871a0cb81 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -14,12 +14,8 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	// because of issue https://github.com/go-gitea/gitea/issues/11949,
 	// recalculate Stars number for all users to fully fix it.
 
-	// UserType defines the user type
-	type UserType int
-
 	type User struct {
-		ID   int64 `xorm:"pk autoincr"`
-		Type UserType
+		ID int64 `xorm:"pk autoincr"`
 	}
 
 	const batchSize = 100
@@ -29,20 +25,24 @@ func recalculateStars(x *xorm.Engine) (err error) {
 	for start := 0; ; start += batchSize {
 		users := make([]User, 0, batchSize)
 		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
-			return err
+			return
 		}
 		if len(users) == 0 {
 			break
 		}
 
 		for _, user := range users {
-			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
-				return err
+			if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
+				return
 			}
 		}
+
+		if err = sess.Commit(); err != nil {
+			return
+		}
 	}
 
 	log.Debug("recalculate Stars number for all user finished")
 
-	return sess.Commit()
+	return
 }
diff --git a/models/repo.go b/models/repo.go
index 8509568bf731e..0a3a269d26e17 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -2365,20 +2365,24 @@ func DoctorUserStarNum() (err error) {
 	for start := 0; ; start += batchSize {
 		users := make([]User, 0, batchSize)
 		if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
-			return err
+			return
 		}
 		if len(users) == 0 {
 			break
 		}
 
 		for _, user := range users {
-			if _, err = x.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
-				return err
+			if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
+				return
 			}
 		}
+
+		if err = sess.Commit(); err != nil {
+			return
+		}
 	}
 
 	log.Debug("recalculate Stars number for all user finished")
 
-	return sess.Commit()
+	return
 }

From 3d8af43a4dc749a09742377c211353d578ff229e Mon Sep 17 00:00:00 2001
From: a1012112796 <1012112796@qq.com>
Date: Sat, 27 Jun 2020 22:05:16 +0800
Subject: [PATCH 13/13] add start

---
 models/migrations/v143.go | 4 ++++
 models/repo.go            | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/models/migrations/v143.go b/models/migrations/v143.go
index 8f53871a0cb81..93237ebfcd2e0 100644
--- a/models/migrations/v143.go
+++ b/models/migrations/v143.go
@@ -31,6 +31,10 @@ func recalculateStars(x *xorm.Engine) (err error) {
 			break
 		}
 
+		if err = sess.Begin(); err != nil {
+			return
+		}
+
 		for _, user := range users {
 			if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
 				return
diff --git a/models/repo.go b/models/repo.go
index 0a3a269d26e17..89ce4c8929ecf 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -2371,6 +2371,10 @@ func DoctorUserStarNum() (err error) {
 			break
 		}
 
+		if err = sess.Begin(); err != nil {
+			return
+		}
+
 		for _, user := range users {
 			if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
 				return