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

Stop wrapping single changes in transactions where possible #27500

Merged
merged 7 commits into from
Mar 4, 2022

Conversation

roji
Copy link
Member

@roji roji commented Feb 23, 2022

@AndriySvyryd here's a draft removing the unnecessary transaction where possible.

I got stuck in a thorny chicken and egg issue. To know whether a transaction needs to be started, I need to know if there's more than one batch. So the code as of now always peeks one batch forward; but this fails Can_insert_TPT_dependents_with_identity since GenerateColumnModifications gets called on ModificationCommand in the later batch, and the earlier batch hasn't yet been executed (and so hasn't propagated server-generated keys into the shared InternalEntityEntry).

Hopefully I'm understanding the situation right (am new here). One workaround could be to restart the enumeration if I see more than one batch; this would be optimized for the one-batch case, but would cause multiple enumerations (and so multiple TopologicalSort etc.) for multiple batches - not ideal.

Ideally, while preparing the second batch, we'd already know that the value will be propagated by the time we execute it, even if it hasn't yet been at the time we generate it; this way batch generation would no longer depend on execution order etc. But I have no idea how feasible/reasonable that is.

NOTE: Solved this, see below.

Closes #27439

@roji roji marked this pull request as draft February 23, 2022 23:49
@roji
Copy link
Member Author

roji commented Feb 28, 2022

@AndriySvyryd FYI I ended up solving the above by changing CommandBatchPreparer to allow checking if there is another batch up ahead, but without actually generating it; this makes CommandBatchPreparer itself behave like an enumerator, and unfortunately means we can't use yield.

Technically, this still isn't as good as being able to generate all the batches without executing any, since the current logic may return that there are batches, whereas when we actually get around to generate them, we find that there are no modifications to be done (i.e. update without write operations). In that case we'd get a transaction though we don't need, but that seems like an acceptable edge case.

Let me know what you think - this PR is close to ready, mostly test cleanup remains.

@AndriySvyryd
Copy link
Member

I think we can avoid adding the peek API (and perhaps go back to using yield) if we signal that there are still more commands afterwards by adding a parameter to ModificationCommandBatch.Complete that will affect the value of ModificationCommandBatch.RequiresTransaction.

Note that ModificationCommandBatch.Complete will be removed by #20664 since ModificationCommandBatch.AddCommand will always be called on the current batch before starting the next one.

@roji
Copy link
Member Author

roji commented Mar 1, 2022

I think we can avoid adding the peek API (and perhaps go back to using yield) if we signal that there are still more commands afterwards by adding a parameter to ModificationCommandBatch.Complete that will affect the value of ModificationCommandBatch.RequiresTransaction.

Thanks for this suggestion... I ended up doing something which may be even better: BatchCommands now simply returns a tuple of batches and "HasMore" flags. This avoids putting information in the batch itself on whether more batches are coming, and also avoids depending on Complete in case it goes away.

Note that ModificationCommandBatch.Complete will be removed by #20664 since ModificationCommandBatch.AddCommand will always be called on the current batch before starting the next one.

OK, yeah, we should discuss so I understand what you have in mind.

@roji roji force-pushed the Untransactionize branch 2 times, most recently from ab582fb to a41de1e Compare March 1, 2022 19:15
@roji roji marked this pull request as ready for review March 1, 2022 19:15
@roji
Copy link
Member Author

roji commented Mar 1, 2022

Login issues to SQL Server on Helix...

Co-authored-by: Andriy Svyryd <AndriySvyryd@users.noreply.github.com>
…or.cs

Co-authored-by: Andriy Svyryd <AndriySvyryd@users.noreply.github.com>
@roji roji merged commit fe5bebc into dotnet:main Mar 4, 2022
@roji roji deleted the Untransactionize branch March 4, 2022 00:24
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.

Stop wrapping single changes in transactions where possible
2 participants