sql server - Concurrency exception in Entity Framework when loading and deleting objects -


i've got ef class mapped sql server table. have following simple entity framework code (using asp.net boilerplate repository wrapper on ef dbcontext):

var objectstodelete = repository.getall().where(r => r.parentid == param1).tolist(); foreach(var obj in objectstodelete) {     repository.delete(obj); //doesn't update database yet. } ... repository.savechanges(); 

note getall call read database.

surprisingly me, real concurrency headache when multiple web service calls try run code simultaneously same param1 value (imagine user performs exact same action twice in quick succession). cut long story short, context switch can occur between getting ids , calling savechanges. happens (you can change order around quite bit without affecting result):

  1. thread #1 starts sql transaction , starts running above code.
  2. thread #2 starts sql transaction , starts running above code (using different dbcontext).
  3. thread #1 gets objects delete.
  4. context switch.
  5. thread #2 gets objects delete - have same ids #1 read.
  6. thread #2 marks objects deleted , calls savechanges, issues sql delete statements.
  7. thread #2 commits transaction , it's done.
  8. thread #1, using (now stale) list, marks same objects deleted , calls savechanges, issues sql delete statements.
  9. exception! entity throws this:

store update, insert, or delete statement affected unexpected number of rows (0).

now, if turn transaction isolation level way serializable, doesn't help. "serializable" specifies statements cannot read data has been modified not yet committed other transactions. problem occurred in step 5, , @ point nothing had been modified. ah, serializable specifies no other transactions can modify data has been read current transaction until current transaction completes. okay, in above sequence thread #2 block @ step 6. shifts problem without addressing it. whichever thread second 1 attempt delete encounter 'unexpected rowcount' exception.

i can't see prevention - treatment. seems have either swallow exception or turn off entity framework's validation-on-save. , since i'm using asp.net boilerplate, doesn't seem convenient. i’m puzzled apparently simple , typical isn’t easier control. missing?

var objectstodelete = repository.getall().where(r => r.parentid == param1).tolist(); if(objectstodelete.count!=0) {     repository.removerange(objectstodelete );  } ... repository.savechanges(); 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -