OptimisticConcurrencyException exception using System.Web.Providers

I am using Microsoft's new Universal Providers for a session in SQL Server. An old session implementation on SQL Server required a job (every minute) to clear expired sessions. A new one checks and clears every request. Since I actually work in SQL Azure, I don’t have an SQL agent for scheduling tasks, so this sounds like a smart way around this (no, I don’t want to pay for Azure Cache for the session).

The problem is that several users are accessing the site at the same time, both are trying to clear the same expired sessions at the same time, and the second gets an optimistic concurrency exception.

System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Web.Providers.DefaultSessionStateProvider.PurgeExpiredSessions() at System.Web.Providers.DefaultSessionStateProvider.PurgeIfNeeded() at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

I use ELMAH to record errors, and this shows up with some frequency. Before trying to set ELMAH to ignore errors, does anyone know how to stop errors in the first place? Is there some kind of configuration with the new providers that I am missing?

+6
source share
3 answers

This package has what I would call a mistake. A prerequisite for not having a process session is that multiple instances can control how the session state is cleared. In this case, all instances run this method ...

 private void PurgeExpiredSessions() { using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) { foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities)) { entities.DeleteObject(entity); } entities.SaveChanges(); this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; } } 

The problem is that one instance deletes entities in front of the other (s), and entities generates the error described in the message. I asked the authors of the package to free the source code or fix it. My patched text editor fix would be to add a public virtual one, so you can override the method or just change it too.

 private void PurgeExpiredSessions() { using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) { var sqlCommand = @"DELETE dbo.Sessions WHERE Expires < GETUTCDATE()"; entities.ExecuteStoreCommand(sqlCommand); this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; } } 

The authors of the packages are very quick to answer (answered when publishing this!), And today they stated that they are working on the release of the code, but can simply fix it. I asked ETA and will try to keep an eye on him if I get it.

Great package, it just needs a little maintenance.

The correct answer is: wait until the source code is released or the patch is updated. Or decompile and fix it yourself (if it is consistent with the license!)

* Updating package owners is considering fixing it this week. Yes! ** Update.SOLVED !!! They obviously fixed it a while ago, and I installed the wrong package. I used http://nuget.org/packages/System.Web.Providers , and I had to use http://nuget.org/packages/Microsoft.AspNet.Providers/ .. It was not obvious to me which one was heir and included in another package. They wrapped him in an empty catch.

 private void PurgeExpiredSessions() { try { using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) { foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities)) { entities.DeleteObject(entity); } entities.SaveChanges(); this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; } } catch { } } 

Thanks to the package team for such quick answers and great support!

+1
source

Download the newer version of providers, which can be found here: http://www.nuget.org/packages/System.Web.Providers . We've updated the way to clear expired sessions to start asynchronously and handle errors. Please let us know if they do not fix your problems.

+2
source

I posted a question about this on NuGet (http://www.nuget.org/packages/System.Web.Providers) and received a very quick response from the owners. After a little back and forth, it turns out they have a fix for this, but comes out in the next update.

It has been suggested that Microsoft is not too keen on this, but my experience was otherwise and always received good support.

+1
source

Source: https://habr.com/ru/post/911509/


All Articles