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

Transaction management made async #6809

Merged
merged 39 commits into from
Jan 3, 2021
Merged

Transaction management made async #6809

merged 39 commits into from
Jan 3, 2021

Conversation

hikalkan
Copy link
Member

We were using sync API to begin transaction. I converted it to async and it brings a significant scalability increase.
But we have a cost: We can not use LINQ extension methods directly on the IRepository. Instead, we should use await IRepository.GetQueryableAsync(). Because ABP internally may begin transaction with this method call.

This doesn't make breaking change, however I made a lot of methods Obsolete and we may remove them in the future which will be a major breaking change.

I updated all the usages including modules.

I will update all the documentation and tutorials. Also, I will write a blog post about that since it effects almost all applications.

@maliming
Copy link
Member

I wanted to do this, but I was stuck with IQueryable. 👍

@hikalkan
Copy link
Member Author

hikalkan commented Dec 24, 2020

I want to continue to use LINQ extension methods directly on IRepository. However, we should find a way to defer DbContext creation until we execute the query. When the query executed, we can intercept it, create dbcontext & begin transaction, then delegate query execution to underlying provider (EF Core / MongoDB). However, I couldn't find how can I do it easily. We may need to create a custom LINQ provider for the repository but this is not easy to implement. Still thinking on. If you find a way, please write to me.

@hikalkan
Copy link
Member Author

I made a demo to demonstrate how we can do it with creating custom wrapper methods to all linq extension methods (Where, OrderBy, ToList, ToListAsync...).
https://github.com/hikalkan/samples/tree/master/EfCoreLinqWrapper/EfCoreLinqWrapper

It is a huge work, but separates creating dbcontext and starting transaction. We can defer starting transaction in this way.
This requires a lot of work and makes most of my work in this PR goes away. However, we will have two important gains;

  • No need to use await IRepository.GetQueryableAsync() which is what I don't like.
  • Fully support LINQ async methods without depending on EFCore/MongoDB. We currently partially support it.

I will continue to work on this.

@hikalkan hikalkan marked this pull request as ready for review December 25, 2020 18:01
@hikalkan
Copy link
Member Author

hikalkan commented Jan 2, 2021

Separating dbcontext creation (and obtaining the queryable) and starting transaction didn't work for mongodb. It requires to relate the transaction while obtaining the queryable. It works for EF Core, but the implementation is complicated.

Anyway, currently, the best thing we can do is to suggest to use await repository.GetQueryablyAsync to obtain the queryable instead of directly write query on the repository. Since this would be a breaking change almost for all applications, I left the current usage possible. I made Obsolete wherever possible. We probably will remove IRepository : IQueryable inheritence in the next major version.

@maliming maliming merged commit 4185454 into dev Jan 3, 2021
@hikalkan hikalkan deleted the async-uow-transaction branch January 3, 2021 08:37
@enisn enisn mentioned this pull request Jan 4, 2021
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.

2 participants