0
wazbek created
Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, and please first use the search on the homepage. Provide us with the following info:
- ABP Framework version: v8.0.3
- UI Type: Angular
- Database System: EF Core (Oracle) using the Devart driver
- Tiered (for MVC) or Auth Server Separated (for Angular): Auth Server Separated (for Angular)
- Exception message and full stack trace:
[ERR] Transaction isolation level RepeatableRead not supported.
System.ArgumentException: Transaction isolation level RepeatableRead not supported.
at Devart.Data.Oracle.OracleTransaction..ctor(OracleConnection A_0, IsolationLevel A_1)
at Devart.Data.Oracle.OracleConnection.BeginTransaction(IsolationLevel il)
at Devart.Data.Oracle.OracleConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at Devart.Common.Entity.ct.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.Common.DbConnection.BeginDbTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken)
--- End of stack trace from previous location ---
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider
1.CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider
1.CreateDbContextAsync(IUnitOfWork unitOfWork) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.CreateDbContextAsync(IUnitOfWork unitOfWork, String connectionStringName, String connectionString) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider
1.GetDbContextAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.GetDbSetAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository
2.GetQueryableAsync() at Volo.Abp.OpenIddict.Tokens.EfCoreOpenIddictTokenRepository.PruneAsync(DateTime date, CancellationToken cancellationToken) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) at Volo.Abp.OpenIddict.Tokens.AbpOpenIddictTokenStore.PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) at Volo.Abp.OpenIddict.Tokens.TokenCleanupService.CleanAsync() - Steps to reproduce the issue: The issue is happening in this code when the TokenCleanupBackgroundWorker runs:
3 Answer(s)
-
0
hi
You can override these methods to use another
IsolationLevel
, I will make it configurable in the next version.Your question credit has been refunded.
-
0
hi @maliming
What is the best way to override them?
Thanks.
-
0
hi
public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddOpenIddict() .AddCore(builder => { builder .AddApplicationStore<MyAbpOpenIddictApplicationStore>() .AddAuthorizationStore<MyAbpOpenIddictAuthorizationStore>() .AddTokenStore<MyAbpOpenIddictTokenStore>(); }); }
public class MyAbpOpenIddictApplicationStore : AbpOpenIddictApplicationStore { public MyAbpOpenIddictApplicationStore(IOpenIddictApplicationRepository repository, IUnitOfWorkManager unitOfWorkManager, IOpenIddictTokenRepository tokenRepository, IGuidGenerator guidGenerator, AbpOpenIddictIdentifierConverter identifierConverter, IOpenIddictDbConcurrencyExceptionHandler concurrencyExceptionHandler) : base(repository, unitOfWorkManager, tokenRepository, guidGenerator, identifierConverter, concurrencyExceptionHandler) { } public async override ValueTask DeleteAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken) { Check.NotNull(application, nameof(application)); try { using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true, isolationLevel: IsolationLevel.ReadCommitted)) { await TokenRepository.DeleteManyByApplicationIdAsync(application.Id, cancellationToken: cancellationToken); await Repository.DeleteAsync(application.Id, cancellationToken: cancellationToken); await uow.CompleteAsync(cancellationToken); } } catch (AbpDbConcurrencyException e) { Logger.LogException(e); await ConcurrencyExceptionHandler.HandleAsync(e); throw new OpenIddictExceptions.ConcurrencyException(e.Message, e.InnerException); } } } public class MyAbpOpenIddictAuthorizationStore : AbpOpenIddictAuthorizationStore { public MyAbpOpenIddictAuthorizationStore(IOpenIddictAuthorizationRepository repository, IUnitOfWorkManager unitOfWorkManager, IGuidGenerator guidGenerator, IOpenIddictApplicationRepository applicationRepository, IOpenIddictTokenRepository tokenRepository, AbpOpenIddictIdentifierConverter identifierConverter, IOpenIddictDbConcurrencyExceptionHandler concurrencyExceptionHandler) : base(repository, unitOfWorkManager, guidGenerator, applicationRepository, tokenRepository, identifierConverter, concurrencyExceptionHandler) { } public async override ValueTask DeleteAsync(OpenIddictAuthorizationModel authorization, CancellationToken cancellationToken) { Check.NotNull(authorization, nameof(authorization)); try { using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true, isolationLevel: IsolationLevel.ReadCommitted)) { await TokenRepository.DeleteManyByAuthorizationIdAsync(authorization.Id, cancellationToken: cancellationToken); await Repository.DeleteAsync(authorization.Id, cancellationToken: cancellationToken); await uow.CompleteAsync(cancellationToken); } } catch (AbpDbConcurrencyException e) { Logger.LogException(e); await ConcurrencyExceptionHandler.HandleAsync(e); throw new OpenIddictExceptions.ConcurrencyException(e.Message, e.InnerException); } } public async override ValueTask<long> PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) { using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true, isolationLevel: IsolationLevel.ReadCommitted)) { var date = threshold.UtcDateTime; var count = await Repository.PruneAsync(date, cancellationToken: cancellationToken); await uow.CompleteAsync(cancellationToken); return count; } } } public class MyAbpOpenIddictTokenStore : AbpOpenIddictTokenStore { public MyAbpOpenIddictTokenStore(IOpenIddictTokenRepository repository, IUnitOfWorkManager unitOfWorkManager, IGuidGenerator guidGenerator, IOpenIddictApplicationRepository applicationRepository, IOpenIddictAuthorizationRepository authorizationRepository, AbpOpenIddictIdentifierConverter identifierConverter, IOpenIddictDbConcurrencyExceptionHandler concurrencyExceptionHandler) : base(repository, unitOfWorkManager, guidGenerator, applicationRepository, authorizationRepository, identifierConverter, concurrencyExceptionHandler) { } public async override ValueTask<long> PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) { using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true, isolationLevel: IsolationLevel.ReadCommitted)) { var date = threshold.UtcDateTime; var count = await Repository.PruneAsync(date, cancellationToken: cancellationToken); await uow.CompleteAsync(cancellationToken); return count; } } }