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

chore: requery account for transaction isolation #700

Merged
merged 1 commit into from
Oct 12, 2023

Conversation

lzap
Copy link
Member

@lzap lzap commented Oct 9, 2023

So I came up with this nice trick on how to quickly create accounts without explicit transactions. Works great, except it does not :-) When there are actually two requests with the same account at the same time, the query is executed in an implicit transactions which cannot be turned off and I totally forgot about it.

What happens is that one request will fail with pgx error: scanning one: no rows in result set (https://glitchtip.devshift.net/insights/issues/973561) because although the conflict will trigger, the default isolation level in postgres will not allow to see the inserted record.

The solution is to execute the same query one more time, this only happens rarely, I saw 20 events in production in one week. But it is worth fixing this.

This is hard to test or reproduce, so review carefully. Maybe with some arbitrary sleep via pg_sleep() function but I find this difficult to figure out. I think the code is good (TM).

@akhil-jha
Copy link
Member

/retest

@@ -76,6 +77,15 @@ func (x *accountDao) GetOrCreateByIdentity(ctx context.Context, orgId string, ac
return nil, fmt.Errorf("pgx error: %w", err)
}

// Step 4: requery in case transaction isolation (simultaneous transactions)
if result.ID == 0 && result.OrgID == "" {
Copy link
Member

Choose a reason for hiding this comment

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

Query again makes sense (it will increase the chances of success :) ), but will we ever trigger this, given we return on error few lines before?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah right, I thought empty result is not an error while in fact it actually is. Rebased a new version.

Copy link
Member

@ezr-ondrej ezr-ondrej left a comment

Choose a reason for hiding this comment

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

I'm good, but the linter ain't happy now.

Comment on lines 82 to 87
err := pgxscan.Get(ctx, db.Pool, result, query, orgId, account)
if err != nil {
return nil, fmt.Errorf("pgx requery error: %w", err)
}
}
} else if err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Linter doesn't like shadowing the var.
We can use the same var and use the same if for catching all the "leftover" errors in the main, right?

Smthing like:

Suggested change
err := pgxscan.Get(ctx, db.Pool, result, query, orgId, account)
if err != nil {
return nil, fmt.Errorf("pgx requery error: %w", err)
}
}
} else if err != nil {
err = pgxscan.Get(ctx, db.Pool, result, query, orgId, account)
}
}
if err != nil {

or just use requeryErr var would also work :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Rebased

@ezr-ondrej
Copy link
Member

/retest

@lzap
Copy link
Member Author

lzap commented Oct 11, 2023

All good.

Copy link
Member

@ezr-ondrej ezr-ondrej left a comment

Choose a reason for hiding this comment

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

Thanks @lzap ! 👍

@ezr-ondrej ezr-ondrej merged commit 577868d into RHEnVision:main Oct 12, 2023
6 checks passed
@lzap lzap deleted the acc-requery branch October 12, 2023 10:59
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

Successfully merging this pull request may close these issues.

3 participants