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

SelectOrInsert is not safe for transactions #1880

Open
tbarbugli opened this issue May 7, 2021 · 0 comments
Open

SelectOrInsert is not safe for transactions #1880

tbarbugli opened this issue May 7, 2021 · 0 comments

Comments

@tbarbugli
Copy link

Say that you have something like this:

db.RunInTransaction(ctx, func(tx *pg.Tx) error {
   inserted, err := tx.Model(). SelectOrInsert()
})

if this code runs concurrently you will get a transaction aborted error instead of a nil error. This happens because SelectOrInsert does this inside of a retry loop:

if err != nil {
	insertErr = err
	if err == internal.ErrNoRows {
		continue
	}
	if pgErr, ok := err.(internal.PGError); ok {
		if pgErr.IntegrityViolation() {
			continue
		}
		if pgErr.Field('C') == "55000" {
			// Retry on "#55000 attempted to delete invisible tuple".
			continue
		}
	}
	return false, err
}

which is OK unless you are doing this inside a transaction, the moment you hit an error the transaction will be aborted and the next SELECT will error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant