From cc3910d8c32f0c63257ff09ff5b9174d6224157b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 15 Jun 2023 08:14:43 +0800 Subject: Fix index generation parallelly failure (#25235) Fix #22109 --------- Co-authored-by: silverwind --- models/git/commit_status.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'models/git') diff --git a/models/git/commit_status.go b/models/git/commit_status.go index a018bb0553..49143a87e8 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -83,13 +83,47 @@ func mysqlGetCommitStatusIndex(ctx context.Context, repoID int64, sha string) (i return idx, nil } +func mssqlGetCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) { + if _, err := db.GetEngine(ctx).Exec(` +MERGE INTO commit_status_index WITH (HOLDLOCK) AS target +USING (SELECT ? AS repo_id, ? AS sha) AS source +(repo_id, sha) +ON target.repo_id = source.repo_id AND target.sha = source.sha +WHEN MATCHED + THEN UPDATE + SET max_index = max_index + 1 +WHEN NOT MATCHED + THEN INSERT (repo_id, sha, max_index) + VALUES (?, ?, 1); +`, repoID, sha, repoID, sha); err != nil { + return 0, err + } + + var idx int64 + _, err := db.GetEngine(ctx).SQL("SELECT max_index FROM `commit_status_index` WHERE repo_id = ? AND sha = ?", + repoID, sha).Get(&idx) + if err != nil { + return 0, err + } + if idx == 0 { + return 0, errors.New("cannot get the correct index") + } + return idx, nil +} + // GetNextCommitStatusIndex retried 3 times to generate a resource index func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) { + if !git.IsValidSHAPattern(sha) { + return 0, git.ErrInvalidSHA{SHA: sha} + } + switch { case setting.Database.Type.IsPostgreSQL(): return postgresGetCommitStatusIndex(ctx, repoID, sha) case setting.Database.Type.IsMySQL(): return mysqlGetCommitStatusIndex(ctx, repoID, sha) + case setting.Database.Type.IsMSSQL(): + return mssqlGetCommitStatusIndex(ctx, repoID, sha) } e := db.GetEngine(ctx) -- cgit v1.2.3