graphql-platform: Synchronized DbContext is not synchronized in data loaders
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Have a data loader tha uses DbContext:
public class EntityByIdDataLoader<TEntity>: BatchDataLoaderWithDbContext<int, TEntity>
where TEntity : class, IEntity
{
public EntityByIdDataLoader(CommonDbContext dbContext, IBatchScheduler batchScheduler, DataLoaderOptions? options = null)
: base(dbContext, batchScheduler, options)
{
}
protected override async Task<IReadOnlyDictionary<int, TEntity>> LoadBatchAsync(IReadOnlyList<int> keys,
CommonDbContext dbContext, CancellationToken cancellationToken)
=> await dbContext.Set<TEntity>().Where(e => keys.Contains(e.Id)).ToDictionaryAsync(k => k.Id, k => k, cancellationToken);
}
Have a resolver that uses two of these loaders:
[GraphQLType(typeof(UserNoteRelatedEntityUnionType))]
public async Task<object?> GetRelatedEntityAsync([Parent] UserNote parent,
[DataLoader] EntityByIdDataLoader<Instrument> instrumentLoader,
[DataLoader] EntityByIdDataLoader<Instruction> instructionLoader,
[Service] IMapper mapper,
CancellationToken token)
=> parent.RelatedEntityType switch
{
UserNoteRelatedEntityType.Instrument => await instrumentLoader.LoadAsync(parent.RelatedEntityId!.Value, token),
UserNoteRelatedEntityType.Instruction =>
mapper.Map<ViewInstruction>(await instructionLoader.LoadAsync(parent.RelatedEntityId!.Value, token)),
_ => null,
};
Occasionaly get:
A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
on path
[
"userNotes",
"nodes",
2,
"relatedEntity"
]
Steps to reproduce
- See above
Relevant log output
No response
Additional Context?
DbContext is registered as synchronized:
services.AddGraphQLServer().RegisterDbContext<CommonDbContext>(DbContextKind.Synchronized);
I thought I could enforce synchronization by adding DbContext explicitly as a parameter of the resover. However, this leads to endlessly running query.
Product
Hot Chocolate
Version
12.9.0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 16 (9 by maintainers)
@nzbart we have a transaction abstraction that wraps around the whole request … you can implement this.
@michaelstaib The issue in doc I see in https://chillicream.com/docs/hotchocolate/integrations/entity-framework/#working-with-a-pooled-dbcontext the last paragraph implies that if u are using pooled, change data loaders this way, otherwise use let them access DbContext directly. The phrase “a look at some of the changes you have to make” in conjuction with chapter “DataLoaders” implies that you already have a data loader that uses DbContext (directly) and that you have to change it this way to work with pooled DbContext.