У меня есть сервис WCF
, который должен возвращать объекты из базы данных, но каждый объект должен быть возвращен только один раз.Я хотел бы избежать сценария, когда многие клиенты используют сервис и могут получить одну и ту же сущность Request
.
public Request GetChangeRequest()
{
using (var context = new Data.Core.Context())
{
var request = context.Requests
.Where(r => r.IsAvaible)
.FirstOrDefault();
if (request != null)
{
request.IsAvaible = false;
context.SaveChanges();
}
return request;
}
}
Мне действительно интересно, есть ли причина для обеспечения дополнительной безопасности, такой как блокировка базы данных.Для этого мне удалось что-то вроде этого:
public Request GetChangeRequest()
{
using (var context = new Data.Core.Context())
{
context.OnLock<Request>(context.GetTableName<Request>(), () =>
{
var request = context.Requests
.Where(r => r.IsAvaible)
.FirstOrDefault();
if (request != null)
{
request.IsAvaible = false;
context.SaveChanges();
}
return request;
});
}
}
public static class DBContextExtensions
{
public static string GetTableName<T>(this DbContext context) where T : class
{
var type = typeof(T);
var entityName = (context as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.CreateObjectSet<T>().EntitySet.Name;
var tableAttribute = type.GetCustomAttributes(false).OfType<System.ComponentModel.DataAnnotations.Schema.TableAttribute>().FirstOrDefault();
return tableAttribute == null ? entityName : tableAttribute.Name;
}
public static T OnLock<T>(this DbContext context, string tableName, Func<T> action)
{
T res;
using (DbContextTransaction scope = context.Database.BeginTransaction())
{
context.Database.ExecuteSqlCommand($"SELECT TOP 1 Id FROM {tableName} WITH (TABLOCKX, HOLDLOCK)");
res = action.Invoke();
scope.Commit();
}
return res;
}
}
Я не смог воспроизвести scenerio, когда два объекта запроса возвращаются двум разным клиентам.Означает ли это, что WCF
сервис выполняет запросы последовательно?