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

Replace unnecesary calls to SaveChangesAsync by FlushAsync #17084

Merged
merged 2 commits into from
Nov 28, 2024

Conversation

sebastienros
Copy link
Member

@sebastienros
Copy link
Member Author

@kevinchalet just because we talked about these years ago and you might remember something that I don't.

@kevinchalet
Copy link
Member

I'm not familiar enough with YesSql to know the differences between SaveChangeAsync() and FlushAsync(), but assuming concurrency checks and unique indexes checks are performed by FlushAsync(), that should work.

I guess one risk of making this change is that some exceptions might surface elsewhere, when the session is committed higher in the stack, rather than in the stores themselves?

@sebastienros
Copy link
Member Author

FlushAsync executes the pending SQL statements without committing the transaction, while SaveChangesAsync will call FlushAsync and commit the transaction, and clear the identity map ... The last part has the effect that the following SELECTS will return fresh data instead of local caches (identity map, aka first level cache, aka reference cache). But in most cases that is fine for a session that is linked to a request, because you get the same data during the whole request this way instead of dealing with different objects representing the same record, but with different state eventually. Concurrency checks would still work since they are doing pessimistic concurrency using the version field.

Calling SaveChangesAsync makes sense if you use a long running session for multiple work units, where you want to refresh your entities on the next SELECTS. But then you need to be careful not to call "Save" on a previously loaded item or YesSql could throw an exception.

@sebastienros
Copy link
Member Author

Functional tests are still passing on this branch. https://github.com/OrchardCMS/OrchardCore/actions/runs/12042510905

Doesn't mean that everything was tested. How awesome would it be if we have functional tests for these operations, including concurrency checks.

Copy link
Member

@MikeAlhayek MikeAlhayek left a comment

Choose a reason for hiding this comment

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

looks good to me

@kevinchalet
Copy link
Member

@sebastienros makes sense, thanks the detailed explanation 👍🏻

(but just in case, that might be worth testing a complete authorization code flow using Postman, to ensure nothing regressed).

Copy link
Member

@deanmarcussen deanmarcussen left a comment

Choose a reason for hiding this comment

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

Yeah, I think this is fine.

@kevinchalet largely had me calling SaveChangesAsync to ensure that IdentityResult.Failed was the result of an actual sql failure during the session, rather than an exception later in the chain, but when running the transaction through the lifetime of the request, it makes more sense to me to flush it, but leave the transaction still open.

@MikeAlhayek MikeAlhayek merged commit d016259 into main Nov 28, 2024
22 checks passed
@MikeAlhayek MikeAlhayek deleted the sebros/nosavechanges branch November 28, 2024 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants