The Wayback Machine - https://web.archive.org/web/20230320165457/https://github.com/go-gitea/gitea/pull/22362
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always reuse transaction #22362

Merged
merged 5 commits into from Jan 8, 2023
Merged

Conversation

wolfogre
Copy link
Member

@wolfogre wolfogre commented Jan 7, 2023

I don't see any cases where we have to create a new transaction instead of reusing the transaction in context. So:

  • Combine WithTx and AutoTx to WithTx, and it always reuses the transaction if it exists;
  • Make TxContext reuse the transaction if it exists, and it will return halfCommitter when reusing.
  • halfCommitter implements Committer, but it does nothing when committing, so it's possible to close a reused transaction early, but impossible to commit it early.
  • Remove ErrAlreadyInTransaction, I don't see any errors.Is(err, db.ErrAlreadyInTransaction), and we don't need it any longer.

After this, we can refactor db.TxContext(db.DefaultContext) to db.TxContext(ctx) safely, and feel free to use db.TxContext or db.WithTx in (almost) any functions as long as there is a ctx. I know it's better to use db.WithTx instead of db.TxContext, but for refactoring, I don't think so, it will cause lots of lines to change because an anonymous function is required.

@wolfogre wolfogre added this to the 1.19.0 milestone Jan 7, 2023
lunny
lunny approved these changes Jan 7, 2023
@codecov-commenter
Copy link

Codecov Report

Merging #22362 (e759b13) into main (d42b52f) will increase coverage by 48.13%.
The diff coverage is 87.87%.

@@            Coverage Diff            @@
##           main   #22362       +/-   ##
=========================================
+ Coverage      0   48.13%   +48.13%     
=========================================
  Files         0     1046     +1046     
  Lines         0   142384   +142384     
=========================================
+ Hits          0    68535    +68535     
- Misses        0    65667    +65667     
- Partials      0     8182     +8182     
Impacted Files Coverage Δ
models/db/error.go 32.14% <ø> (ø)
models/issues/issue.go 52.41% <0.00%> (ø)
models/project/project.go 35.23% <0.00%> (ø)
models/db/context.go 68.37% <92.00%> (ø)
models/activities/notification.go 62.16% <100.00%> (ø)
models/repo/collaboration.go 49.47% <100.00%> (ø)
models/repo_transfer.go 43.46% <100.00%> (ø)
modules/notification/ui/ui.go 60.11% <100.00%> (ø)
modules/repository/collaborator.go 68.42% <100.00%> (ø)
services/issue/comments.go 60.43% <100.00%> (ø)
... and 1046 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

delvh
delvh approved these changes Jan 7, 2023
// 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure if this is the definitive answer.
I'll accept it for now, but I think it would be better if Commit would still be possible with the behavior that it opens a new transaction afterward.

@lunny lunny merged commit 6135359 into go-gitea:main Jan 8, 2023
2 checks passed
zjjhot added a commit to zjjhot/gitea that referenced this pull request Jan 9, 2023
* upstream/main:
  Replace `can not` with `cannot` (go-gitea#22372)
  Fix set system setting failure once it cached (go-gitea#22333)
  Bump json5 from 1.0.1 to 1.0.2 (go-gitea#22365)
  Always reuse transaction (go-gitea#22362)
  make /{username}.png redirect to user/org avatar (go-gitea#22356)
  Remove old HookEventType (go-gitea#22358)
lunny added a commit that referenced this pull request Jan 9, 2023
After #22362, we can feel free to use transactions without
`db.DefaultContext`.

And there are still lots of models using `db.DefaultContext`, I think we
should refactor them carefully and one by one.

Co-authored-by: Lunny Xiao <[email protected]>
@wolfogre wolfogre mentioned this pull request Jan 9, 2023
techknowlogick added a commit that referenced this pull request Jan 9, 2023
Related to #22362.

I overlooked that there's always `committer.Close()`, like:

```go
		ctx, committer, err := db.TxContext(db.DefaultContext)
		if err != nil {
			return nil
		}
		defer committer.Close()

		// ...

		if err != nil {
			return nil
		}

		// ...

		return committer.Commit()
```

So the `Close` of `halfCommitter` should ignore `commit and close`, it's
not a rollback.

See: [Why `halfCommitter` and `WithTx` should rollback IMMEDIATELY or
commit
LATER](#22366 (comment)).

Co-authored-by: techknowlogick <[email protected]>
fsologureng pushed a commit to fsologureng/gitea that referenced this pull request Jan 24, 2023
fsologureng pushed a commit to fsologureng/gitea that referenced this pull request Jan 24, 2023
After go-gitea#22362, we can feel free to use transactions without
`db.DefaultContext`.

And there are still lots of models using `db.DefaultContext`, I think we
should refactor them carefully and one by one.

Co-authored-by: Lunny Xiao <[email protected]>
fsologureng pushed a commit to fsologureng/gitea that referenced this pull request Jan 24, 2023
Related to go-gitea#22362.

I overlooked that there's always `committer.Close()`, like:

```go
		ctx, committer, err := db.TxContext(db.DefaultContext)
		if err != nil {
			return nil
		}
		defer committer.Close()

		// ...

		if err != nil {
			return nil
		}

		// ...

		return committer.Commit()
```

So the `Close` of `halfCommitter` should ignore `commit and close`, it's
not a rollback.

See: [Why `halfCommitter` and `WithTx` should rollback IMMEDIATELY or
commit
LATER](go-gitea#22366 (comment)).

Co-authored-by: techknowlogick <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

5 participants