diff --git a/models/activities/notification.go b/models/activities/notification.go
index d20a53a41d..321d543c73 100644
--- a/models/activities/notification.go
+++ b/models/activities/notification.go
@@ -141,7 +141,7 @@ func CountNotifications(ctx context.Context, opts *FindNotificationOptions) (int
// CreateRepoTransferNotification creates notification for the user a repository was transferred to
func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error {
- return db.AutoTx(ctx, func(ctx context.Context) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
var notify []*Notification
if newOwner.IsOrganization() {
diff --git a/models/db/context.go b/models/db/context.go
index 3db8b16528..455f3d1c5d 100644
--- a/models/db/context.go
+++ b/models/db/context.go
@@ -71,6 +71,14 @@ type Engined interface {
// GetEngine will get a db Engine from this context or return an Engine restricted to this context
func GetEngine(ctx context.Context) Engine {
+ if e := getEngine(ctx); e != nil {
+ return e
+ }
+ return x.Context(ctx)
+}
+
+// getEngine will get a db Engine from this context or return nil
+func getEngine(ctx context.Context) Engine {
if engined, ok := ctx.(Engined); ok {
return engined.Engine()
}
@@ -78,7 +86,7 @@ func GetEngine(ctx context.Context) Engine {
if enginedInterface != nil {
return enginedInterface.(Engined).Engine()
}
- return x.Context(ctx)
+ return nil
}
// Committer represents an interface to Commit or Close the Context
@@ -87,10 +95,22 @@ type Committer interface {
Close() error
}
-// TxContext represents a transaction Context
+// halfCommitter is a wrapper of Committer.
+// It can be closed early, but can't be committed early, it is useful for reusing a transaction.
+type halfCommitter struct {
+ Committer
+}
+
+func (*halfCommitter) Commit() error {
+ // do nothing
+ return nil
+}
+
+// TxContext represents a transaction Context,
+// it will reuse the existing transaction in the parent context or create a new one.
func TxContext(parentCtx context.Context) (*Context, Committer, error) {
- if InTransaction(parentCtx) {
- return nil, nil, ErrAlreadyInTransaction
+ if sess, ok := inTransaction(parentCtx); ok {
+ return newContext(parentCtx, sess, true), &halfCommitter{Committer: sess}, nil
}
sess := x.NewSession()
@@ -102,20 +122,11 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
return newContext(DefaultContext, sess, true), sess, nil
}
-// WithTx represents executing database operations on a transaction
-// This function will always open a new transaction, if a transaction exist in parentCtx return an error.
-func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
- if InTransaction(parentCtx) {
- return ErrAlreadyInTransaction
- }
- return txWithNoCheck(parentCtx, f)
-}
-
-// AutoTx represents executing database operations on a transaction, if the transaction exist,
+// WithTx represents executing database operations on a transaction, if the transaction exist,
// this function will reuse it otherwise will create a new one and close it when finished.
-func AutoTx(parentCtx context.Context, f func(ctx context.Context) error) error {
- if InTransaction(parentCtx) {
- return f(newContext(parentCtx, GetEngine(parentCtx), true))
+func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
+ if sess, ok := inTransaction(parentCtx); ok {
+ return f(newContext(parentCtx, sess, true))
}
return txWithNoCheck(parentCtx, f)
}
@@ -202,25 +213,25 @@ func EstimateCount(ctx context.Context, bean interface{}) (int64, error) {
// InTransaction returns true if the engine is in a transaction otherwise return false
func InTransaction(ctx context.Context) bool {
- var e Engine
- if engined, ok := ctx.(Engined); ok {
- e = engined.Engine()
- } else {
- enginedInterface := ctx.Value(enginedContextKey)
- if enginedInterface != nil {
- e = enginedInterface.(Engined).Engine()
- }
- }
+ _, ok := inTransaction(ctx)
+ return ok
+}
+
+func inTransaction(ctx context.Context) (*xorm.Session, bool) {
+ e := getEngine(ctx)
if e == nil {
- return false
+ return nil, false
}
switch t := e.(type) {
case *xorm.Engine:
- return false
+ return nil, false
case *xorm.Session:
- return t.IsInTx()
+ if t.IsInTx() {
+ return t, true
+ }
+ return nil, false
default:
- return false
+ return nil, false
}
}
diff --git a/models/db/context_test.go b/models/db/context_test.go
index e7518a50d8..95a01d4a26 100644
--- a/models/db/context_test.go
+++ b/models/db/context_test.go
@@ -25,8 +25,62 @@ func TestInTransaction(t *testing.T) {
assert.NoError(t, err)
defer committer.Close()
assert.True(t, db.InTransaction(ctx))
- assert.Error(t, db.WithTx(ctx, func(ctx context.Context) error {
+ assert.NoError(t, db.WithTx(ctx, func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
return nil
}))
}
+
+func TestTxContext(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+
+ { // create new transaction
+ ctx, committer, err := db.TxContext(db.DefaultContext)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ assert.NoError(t, committer.Commit())
+ }
+
+ { // reuse the transaction created by TxContext and commit it
+ ctx, committer, err := db.TxContext(db.DefaultContext)
+ engine := db.GetEngine(ctx)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ {
+ ctx, committer, err := db.TxContext(ctx)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ assert.Equal(t, engine, db.GetEngine(ctx))
+ assert.NoError(t, committer.Commit())
+ }
+ assert.NoError(t, committer.Commit())
+ }
+
+ { // reuse the transaction created by TxContext and close it
+ ctx, committer, err := db.TxContext(db.DefaultContext)
+ engine := db.GetEngine(ctx)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ {
+ ctx, committer, err := db.TxContext(ctx)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ assert.Equal(t, engine, db.GetEngine(ctx))
+ assert.NoError(t, committer.Close())
+ }
+ assert.NoError(t, committer.Close())
+ }
+
+ { // reuse the transaction created by WithTx
+ assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
+ assert.True(t, db.InTransaction(ctx))
+ {
+ ctx, committer, err := db.TxContext(ctx)
+ assert.NoError(t, err)
+ assert.True(t, db.InTransaction(ctx))
+ assert.NoError(t, committer.Commit())
+ }
+ return nil
+ }))
+ }
+}
diff --git a/models/db/error.go b/models/db/error.go
index 5860cb4a07..edc8e80a9c 100644
--- a/models/db/error.go
+++ b/models/db/error.go
@@ -4,14 +4,11 @@
package db
import (
- "errors"
"fmt"
"code.gitea.io/gitea/modules/util"
)
-var ErrAlreadyInTransaction = errors.New("database connection has already been in a transaction")
-
// ErrCancelled represents an error due to context cancellation
type ErrCancelled struct {
Message string
diff --git a/models/issues/issue.go b/models/issues/issue.go
index 7988275e69..c474ca61a6 100644
--- a/models/issues/issue.go
+++ b/models/issues/issue.go
@@ -2365,7 +2365,7 @@ func CountOrphanedIssues(ctx context.Context) (int64, error) {
// DeleteOrphanedIssues delete issues without a repo
func DeleteOrphanedIssues(ctx context.Context) error {
var attachmentPaths []string
- err := db.AutoTx(ctx, func(ctx context.Context) error {
+ err := db.WithTx(ctx, func(ctx context.Context) error {
var ids []int64
if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id").
diff --git a/models/project/project.go b/models/project/project.go
index 0a07cfe22a..f432d0bc4c 100644
--- a/models/project/project.go
+++ b/models/project/project.go
@@ -300,7 +300,7 @@ func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
// DeleteProjectByID deletes a project from a repository. if it's not in a database
// transaction, it will start a new database transaction
func DeleteProjectByID(ctx context.Context, id int64) error {
- return db.AutoTx(ctx, func(ctx context.Context) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
p, err := GetProjectByID(ctx, id)
if err != nil {
if IsErrProjectNotExist(err) {
diff --git a/models/repo/collaboration.go b/models/repo/collaboration.go
index 29bcab70f3..7989e5bdf9 100644
--- a/models/repo/collaboration.go
+++ b/models/repo/collaboration.go
@@ -105,7 +105,7 @@ func ChangeCollaborationAccessMode(ctx context.Context, repo *Repository, uid in
return nil
}
- return db.AutoTx(ctx, func(ctx context.Context) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
e := db.GetEngine(ctx)
collaboration := &Collaboration{
diff --git a/models/repo_transfer.go b/models/repo_transfer.go
index 19e6c06627..27a77f9b8c 100644
--- a/models/repo_transfer.go
+++ b/models/repo_transfer.go
@@ -155,7 +155,7 @@ func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error {
// CreatePendingRepositoryTransfer transfer a repo from one owner to a new one.
// it marks the repository transfer as "pending"
func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error {
- return db.AutoTx(ctx, func(ctx context.Context) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
repo, err := repo_model.GetRepositoryByID(ctx, repoID)
if err != nil {
return err
diff --git a/models/system/setting.go b/models/system/setting.go
index 3eb8b3955d..0701c4bf48 100644
--- a/models/system/setting.go
+++ b/models/system/setting.go
@@ -12,7 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/setting"
+ setting_module "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"strk.kbt.io/projects/go/libravatar"
@@ -88,7 +88,7 @@ func GetSettingNoCache(key string) (*Setting, error) {
if len(v) == 0 {
return nil, ErrSettingIsNotExist{key}
}
- return v[key], nil
+ return v[strings.ToLower(key)], nil
}
// GetSetting returns the setting value via the key
@@ -131,7 +131,7 @@ func GetSettings(keys []string) (map[string]*Setting, error) {
type AllSettings map[string]*Setting
func (settings AllSettings) Get(key string) Setting {
- if v, ok := settings[key]; ok {
+ if v, ok := settings[strings.ToLower(key)]; ok {
return *v
}
return Setting{}
@@ -184,14 +184,17 @@ func SetSettingNoVersion(key, value string) error {
// SetSetting updates a users' setting for a specific key
func SetSetting(setting *Setting) error {
- _, err := cache.GetString(genSettingCacheKey(setting.SettingKey), func() (string, error) {
- return setting.SettingValue, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version)
- })
- if err != nil {
+ if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil {
return err
}
setting.Version++
+
+ cc := cache.GetCache()
+ if cc != nil {
+ return cc.Put(genSettingCacheKey(setting.SettingKey), setting.SettingValue, setting_module.CacheService.TTLSeconds())
+ }
+
return nil
}
@@ -243,7 +246,7 @@ func Init() error {
var disableGravatar bool
disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar)
if IsErrSettingIsNotExist(err) {
- disableGravatar = setting.GetDefaultDisableGravatar()
+ disableGravatar = setting_module.GetDefaultDisableGravatar()
disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
} else if err != nil {
return err
@@ -254,7 +257,7 @@ func Init() error {
var enableFederatedAvatar bool
enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar)
if IsErrSettingIsNotExist(err) {
- enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar)
+ enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar)
enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
} else if err != nil {
return err
@@ -262,16 +265,16 @@ func Init() error {
enableFederatedAvatar = disableGravatarSetting.GetValueBool()
}
- if setting.OfflineMode {
+ if setting_module.OfflineMode {
disableGravatar = true
enableFederatedAvatar = false
}
if enableFederatedAvatar || !disableGravatar {
var err error
- GravatarSourceURL, err = url.Parse(setting.GravatarSource)
+ GravatarSourceURL, err = url.Parse(setting_module.GravatarSource)
if err != nil {
- return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting.GravatarSource, err)
+ return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting_module.GravatarSource, err)
}
}
diff --git a/models/system/setting_test.go b/models/system/setting_test.go
index 3ff5ba2520..c43d2e3084 100644
--- a/models/system/setting_test.go
+++ b/models/system/setting_test.go
@@ -33,10 +33,14 @@ func TestSettings(t *testing.T) {
assert.EqualValues(t, newSetting.SettingValue, settings[strings.ToLower(keyName)].SettingValue)
// updated setting
- updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: newSetting.Version}
+ updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: settings[strings.ToLower(keyName)].Version}
err = system.SetSetting(updatedSetting)
assert.NoError(t, err)
+ value, err := system.GetSetting(keyName)
+ assert.NoError(t, err)
+ assert.EqualValues(t, updatedSetting.SettingValue, value)
+
// get all settings
settings, err = system.GetAllSettings()
assert.NoError(t, err)
diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go
index 63a3ffd199..bc66c3d5a3 100644
--- a/modules/notification/ui/ui.go
+++ b/modules/notification/ui/ui.go
@@ -243,7 +243,7 @@ func (ns *notificationService) NotifyPullReviewRequest(ctx context.Context, doer
}
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 {
+ err := db.WithTx(ctx, func(ctx context.Context) error {
return activities_model.CreateRepoTransferNotification(ctx, doer, newOwner, repo)
})
if err != nil {
diff --git a/modules/repository/collaborator.go b/modules/repository/collaborator.go
index f2b9515187..f5cdc35045 100644
--- a/modules/repository/collaborator.go
+++ b/modules/repository/collaborator.go
@@ -14,7 +14,7 @@ import (
)
func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
- return db.AutoTx(ctx, func(ctx context.Context) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
collaboration := &repo_model.Collaboration{
RepoID: repo.ID,
UserID: u.ID,
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index a2528586d9..51ba8866b2 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -95,7 +95,7 @@ copy_content = Copy content
copy_branch = Copy branch name
copy_success = Copied!
copy_error = Copy failed
-copy_type_unsupported = This file type can not be copied
+copy_type_unsupported = This file type cannot be copied
write = Write
preview = Preview
@@ -325,7 +325,7 @@ invalid_code = Your confirmation code is invalid or has expired.
reset_password_helper = Recover Account
reset_password_wrong_user = You are signed in as %s, but the account recovery link is for %s
password_too_short = Password length cannot be less than %d characters.
-non_local_account = Non-local users can not update their password through the Gitea web interface.
+non_local_account = Non-local users cannot update their password through the Gitea web interface.
verify = Verify
scratch_code = Scratch code
use_scratch_code = Use a scratch code
@@ -507,10 +507,10 @@ cannot_add_org_to_team = An organization cannot be added as a team member.
duplicate_invite_to_team = The user was already invited as a team member.
organization_leave_success = You have successfully left the organization %s.
-invalid_ssh_key = Can not verify your SSH key: %s
-invalid_gpg_key = Can not verify your GPG key: %s
+invalid_ssh_key = Cannot verify your SSH key: %s
+invalid_gpg_key = Cannot verify your GPG key: %s
invalid_ssh_principal = Invalid principal: %s
-unable_verify_ssh_key = "Can not verify the SSH key; double-check it for mistakes."
+unable_verify_ssh_key = "Cannot verify the SSH key; double-check it for mistakes."
auth_failed = Authentication failed: %v
still_own_repo = "Your account owns one or more repositories; delete or transfer them first."
@@ -618,7 +618,7 @@ new_password = New Password
retype_new_password = Re-Type New Password
password_incorrect = The current password is incorrect.
change_password_success = Your password has been updated. Sign in using your new password from now on.
-password_change_disabled = Non-local users can not update their password through the Gitea web interface.
+password_change_disabled = Non-local users cannot update their password through the Gitea web interface.
emails = Email Addresses
manage_emails = Manage Email Addresses
@@ -813,7 +813,7 @@ orgs_none = You are not a member of any organizations.
repos_none = You do not own any repositories
delete_account = Delete Your Account
-delete_prompt = This operation will permanently delete your user account. It CAN NOT be undone.
+delete_prompt = This operation will permanently delete your user account. It CANNOT be undone.
delete_with_all_comments = Your account is younger than %s. To avoid ghost comments, all issue/PR comments will be deleted with it.
confirm_delete_account = Confirm Deletion
delete_account_title = Delete User Account
@@ -977,7 +977,7 @@ migrate.clone_address_desc = The HTTP(S) or Git 'clone' URL of an existing repos
migrate.github_token_desc = You can put one or more tokens with comma separated here to make migrating faster because of GitHub API rate limit. WARN: Abusing this feature may violate the service provider's policy and lead to account blocking.
migrate.clone_local_path = or a local server path
migrate.permission_denied = You are not allowed to import local repositories.
-migrate.permission_denied_blocked = You can not import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings.
+migrate.permission_denied_blocked = You cannot import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings.
migrate.invalid_local_path = "The local path is invalid. It does not exist or is not a directory."
migrate.invalid_lfs_endpoint = The LFS endpoint is not valid.
migrate.failed = Migration failed: %v
@@ -1590,7 +1590,7 @@ pulls.wrong_commit_id = "commit id must be a commit id on the target branch"
pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled.
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
-pulls.no_merge_wip = This pull request can not be merged because it is marked as being a work in progress.
+pulls.no_merge_wip = This pull request cannot be merged because it is marked as being a work in progress.
pulls.no_merge_not_ready = This pull request is not ready to be merged, check review status and status checks.
pulls.no_merge_access = You are not authorized to merge this pull request.
pulls.merge_pull_request = Create merge commit
@@ -1926,8 +1926,8 @@ settings.update_settings_success = The repository settings have been updated.
settings.confirm_delete = Delete Repository
settings.add_collaborator = Add Collaborator
settings.add_collaborator_success = The collaborator has been added.
-settings.add_collaborator_inactive_user = Can not add an inactive user as a collaborator.
-settings.add_collaborator_owner = Can not add an owner as a collaborator.
+settings.add_collaborator_inactive_user = Cannot add an inactive user as a collaborator.
+settings.add_collaborator_owner = Cannot add an owner as a collaborator.
settings.add_collaborator_duplicate = The collaborator is already added to this repository.
settings.delete_collaborator = Remove
settings.collaborator_deletion = Remove Collaborator
@@ -2072,7 +2072,7 @@ settings.branches = Branches
settings.protected_branch = Branch Protection
settings.protected_branch_can_push = Allow push?
settings.protected_branch_can_push_yes = You can push
-settings.protected_branch_can_push_no = You can not push
+settings.protected_branch_can_push_no = You cannot push
settings.branch_protection = Branch Protection for Branch '%s'
settings.protect_this_branch = Enable Branch Protection
settings.protect_this_branch_desc = Prevents deletion and restricts Git pushing and merging to the branch.
@@ -2324,7 +2324,7 @@ tag.create_success = Tag '%s' has been created.
topic.manage_topics = Manage Topics
topic.done = Done
-topic.count_prompt = You can not select more than 25 topics
+topic.count_prompt = You cannot select more than 25 topics
topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
find_file.go_to_file = Go to file
@@ -3065,7 +3065,7 @@ raw_minutes = minutes
[dropzone]
default_message = Drop files or click here to upload.
-invalid_input_type = You can not upload files of this type.
+invalid_input_type = You cannot upload files of this type.
file_too_big = File size ({{filesize}} MB) exceeds the maximum size of ({{maxFilesize}} MB).
remove_file = Remove file
diff --git a/package-lock.json b/package-lock.json
index 8e72bd52e1..0bcd9231a3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5916,9 +5916,9 @@
"dev": true
},
"node_modules/json5": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
- "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"bin": {
"json5": "lib/cli.js"
},
@@ -8960,9 +8960,9 @@
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -14248,9 +14248,9 @@
"dev": true
},
"json5": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
- "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ=="
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
"jsonc-parser": {
"version": "2.2.1",
@@ -16540,9 +16540,9 @@
},
"dependencies": {
"json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
diff --git a/services/issue/comments.go b/services/issue/comments.go
index 46c0daf70a..1323fb47aa 100644
--- a/services/issue/comments.go
+++ b/services/issue/comments.go
@@ -123,7 +123,7 @@ func UpdateComment(ctx context.Context, c *issues_model.Comment, doer *user_mode
// DeleteComment deletes the comment
func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
- err := db.AutoTx(ctx, func(ctx context.Context) error {
+ err := db.WithTx(ctx, func(ctx context.Context) error {
return issues_model.DeleteComment(ctx, comment)
})
if err != nil {