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

Use EnterTransaction() before EnterLock(name) exceptions with v5.0.19 #2442

Open
zorgoz opened this issue Mar 5, 2024 · 9 comments
Open

Comments

@zorgoz
Copy link

zorgoz commented Mar 5, 2024

I am using LiteDb as a singleton without any explicit transactions. It is merely a cache for me, not much actual concurrency is there. All tasks use their respective collections, with no concurrency at all on the collection level.
I am getting such an exception:

LiteDB.LiteException: Use EnterTransaction() before EnterLock(name)
at LiteDB.Engine.EngineState.Validate()

Then all consequent calls fail with the same or with:

Object name: 'System.Threading.ReaderWriterLockSlim'.
at System.Threading.ReaderWriterLockSlim.TryEnterReadLockCore(TimeoutTracker timeout)
at System.Threading.ReaderWriterLockSlim.TryEnterReadLock(TimeSpan timeout)
at LiteDB.Engine.LockService.EnterTransaction()

Switching from 5.0.19 back to 5.0.17 instantly solved the issue.

@nefarius
Copy link

nefarius commented Mar 5, 2024

I also use a singleton instance and consume it in a transient service that gets invoked by a scheduler, very simple code I've used in other projects for years and seemingly at random the same issue popped up. I'll try letting my service run with an older version now like you suggested and see if it goes away, thank you!

nefarius added a commit to nefarius/Nefarius.HttpClient.LiteDbCache that referenced this issue Mar 5, 2024
@nefarius
Copy link

nefarius commented Mar 5, 2024

Hm, odd, after the downgrade and letting it run for an hour I now consistently run into a different error with v5.0.17:

[15:45:05 ERR] Unhandled exception in processing job
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Threading.ReaderWriterLockSlim'.
   at System.Threading.ReaderWriterLockSlim.TryEnterReadLockCore(TimeoutTracker timeout)
   at System.Threading.ReaderWriterLockSlim.TryEnterReadLock(TimeSpan timeout)
   at LiteDB.Engine.LockService.EnterTransaction()
   at LiteDB.Engine.TransactionMonitor.GetTransaction(Boolean create, Boolean queryOnly, Boolean& isNew)
   at LiteDB.Engine.LiteEngine.Query(String collection, Query query)
   at LiteDB.LiteQueryable`1.ToDocuments()+MoveNext()
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at Service.Commands.SearchResultCommandHandler.Handle(SearchResultCommand request, CancellationToken cancellationToken)

Faulty code:

internal class SearchResultCommandHandler : IRequestHandler<SearchResultCommand>
{
    private readonly LiteDatabase _db;
    private readonly ILogger<SearchResultCommandHandler> _logger;
    private readonly IMediator _mediator;

    public SearchResultCommandHandler(ILogger<SearchResultCommandHandler> logger, IMediator mediator, LiteDatabase db)
    {
        _logger = logger;
        _mediator = mediator;
        _db = db;
    }

    public Task Handle(SearchResultCommand request, CancellationToken cancellationToken)
    {
        try
        {
            ILiteCollection<StateEntity>? collection = _db.GetCollection<StateEntity>("Searches");

            StateEntity entity = collection.FindOne(entry => entry.SearchTerm == request.SearchTerm) ??
                                 new StateEntity { SearchTerm = request.SearchTerm };
			...
		}
	}
}

I don't really see any API misuse here 🤔

@psavva
Copy link

psavva commented Mar 15, 2024

I an confirm this same

@alexei-lazari
Copy link

the following code worked many months perfect on version 5.0.17, but after upgrade to 5.0.19 it started to fail.

public List<Order> LoadOrdersByStatus(OrderStatus status)
{
	var col = Db.GetCollection<Order>();
	col.EnsureIndex(x => x.OrderStatusId);
	var statusId = (int)status;
	return col.Find(r => r.OrderStatusId == statusId).ToList();
}

LiteDB.LiteException: Use EnterTransaction() before EnterLock(name)
at LiteDB.Engine.LiteEngine.AutoTransaction[T](Func2 fn) at LiteDB.Engine.LiteEngine.EnsureIndex(String collection, String name, BsonExpression expression, Boolean unique) at LiteDB.LiteCollection1.EnsureIndex(String name, BsonExpression expression, Boolean unique)
at Salamander.Data.Logics.OrderStorage.LoadOrdersByStatus(OrderStatus status)
at Salamander.Data.Logics.OrderStorage.LoadUserCartOrder(Nullable1 userId) at Salamander.Data.Logics.OrderStorage.<>c__DisplayClass13_0.<GetUserCartOrderId>b__0(ICacheEntry entry) at Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func2 factory)
at Salamander.WebHost.Pages.Shared.Pages_Shared__LayoutHeaderPartial.ExecuteAsync()
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.RenderPartialViewAsync(TextWriter writer, Object model, IView view)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count)
at Salamander.WebHost.Pages.Shared.Pages_Shared__Layout.b__58_2()
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
at Salamander.WebHost.Pages.Shared.Pages_Shared__Layout.ExecuteAsync()
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

@nefarius
Copy link

Thanks folks, I was starting to think I was imagining things, something sure broke over the past 2 releases 😅

@lanopk
Copy link

lanopk commented Apr 2, 2024

I have the same error, but the location of the error is slightly different.
Occurs in 5.0.19, does not occur in 5.0,16.

DB Update Error : LiteDB.LiteException: Use EnterTransaction() before EnterLock(name)
   at LiteDB.Engine.LockService.EnterLock(String collectionName)
   at LiteDB.Engine.Snapshot..ctor(LockMode mode, String collectionName, HeaderPage header, UInt32 transactionID, TransactionPages transPages, LockService locker, WalIndexService walIndex, DiskReader reader, DiskService disk, Boolean addIfNotExists)
   at LiteDB.Engine.TransactionService.CreateSnapshot(LockMode mode, String collection, Boolean addIfNotExists)
   at LiteDB.Engine.LiteEngine.<>c__DisplayClass27_0.<Update>b__0(TransactionService transaction)
   at LiteDB.Engine.LiteEngine.AutoTransaction[T](Func`2 fn)
   at LiteDB.LiteCollection`1.Update(T entity)

@nefarius
Copy link

nefarius commented May 1, 2024

Could this be recognized and triaged as a bug please, or some explanation provided what we might do wrong otherwise? Cheers.

@bosco688
Copy link

bosco688 commented May 6, 2024

I can confirm this behavior, rolled back to 5.0.17
Also using without any transactions.

@merlokk
Copy link

merlokk commented May 7, 2024

I can confirm this behavior too(, rolled back to 5.0.17

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

No branches or pull requests

7 participants