From 53731393be704e0d6127e2246e35aabf3d1ac596 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Wed, 9 Jun 2021 18:00:59 +0800 Subject: [PATCH] Fix the concurrent pushing the same image issue The transaction will be aborted when get errors during the execution which causes the following sqls report error. This commit moves the re-getting artifact logic out of the second transaction to avoid the concurrent pushing issue Signed-off-by: Wenkai Yin --- src/controller/artifact/controller.go | 20 ++++++++++---------- src/controller/repository/controller.go | 23 +++++++++++------------ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/controller/artifact/controller.go b/src/controller/artifact/controller.go index 56cdbb31ee4..6fd8d19c7a5 100644 --- a/src/controller/artifact/controller.go +++ b/src/controller/artifact/controller.go @@ -199,21 +199,21 @@ func (c *controller) ensureArtifact(ctx context.Context, repository, digest stri if err = orm.WithTransaction(func(ctx context.Context) error { id, err := c.artMgr.Create(ctx, artifact) if err != nil { - // if got conflict error, try to get the artifact again - if errors.IsConflictErr(err) { - var e error - artifact, e = c.artMgr.GetByDigest(ctx, repository, digest) - if e != nil { - err = e - } - } return err } created = true artifact.ID = id return nil - })(ctx); err != nil && !errors.IsConflictErr(err) { - return false, nil, err + })(ctx); err != nil { + // got error that isn't conflict error, return directly + if !errors.IsConflictErr(err) { + return false, nil, err + } + // if got conflict error, try to get the artifact again + artifact, err = c.artMgr.GetByDigest(ctx, repository, digest) + if err != nil { + return false, nil, err + } } return created, artifact, nil diff --git a/src/controller/repository/controller.go b/src/controller/repository/controller.go index 6dbbc4bb224..9fa01ff7972 100644 --- a/src/controller/repository/controller.go +++ b/src/controller/repository/controller.go @@ -104,22 +104,21 @@ func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, erro Name: name, }) if err != nil { - // if got conflict error, try to get again - if errors.IsConflictErr(err) { - var e error - repository, e = c.repoMgr.GetByName(ctx, name) - if e != nil { - err = e - } else { - id = repository.RepositoryID - } - } return err } created = true return nil - })(ctx); err != nil && !errors.IsConflictErr(err) { - return false, 0, err + })(ctx); err != nil { + // isn't conflict error, return directly + if !errors.IsConflictErr(err) { + return false, 0, err + } + // if got conflict error, try to get again + repository, err = c.repoMgr.GetByName(ctx, name) + if err != nil { + return false, 0, err + } + id = repository.RepositoryID } return created, id, nil