I was only able to really accomplish this by manually issuing a lock statement to a table. This does a complete table lock, so be careful with it! In my case it was useful for creating a queue that I didn't want multiple processes touching at once.
using (Entities entities = new Entities())
using (TransactionScope scope = new TransactionScope())
{
//Lock the table during this transaction
entities.Database.ExecuteSqlCommand("SELECT TOP 1 KeyColumn FROM MyTable WITH (TABLOCKX, HOLDLOCK)");
//Do your work with the locked table here...
//Complete the scope here to commit, otherwise it will rollback
//The table lock will be released after we exit the TransactionScope block
scope.Complete();
}
Update - In Entity Framework 6, especially with async
/ await
code, you need to handle the transactions differently. This was crashing for us after some conversions.
using (Entities entities = new Entities())
using (DbContextTransaction scope = entities.Database.BeginTransaction())
{
//Lock the table during this transaction
entities.Database.ExecuteSqlCommand("SELECT TOP 1 KeyColumn FROM MyTable WITH (TABLOCKX, HOLDLOCK)");
//Do your work with the locked table here...
//Complete the scope here to commit, otherwise it will rollback
//The table lock will be released after we exit the TransactionScope block
scope.Commit();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…