gpt4 book ai didi

c# - 如何确保 WCF 服务不会与数据库并行通信

转载 作者:太空宇宙 更新时间:2023-11-03 22:33:46 25 4
gpt4 key购买 nike

我有一个 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;
}
}

当两个请求实体返回给两个不同的客户端时,我无法重现场景。这是否意味着 WCF 服务按顺序执行请求?

最佳答案

与其自行实现锁定机制,一种可能的解决方案是将服务作为单例运行并且不允许并行请求。

您可以通过将 WCF 服务属性 InstanceContextModeConcurrencyMode 设置为 Single 来实现这一点。

有关 session 、实例化和并发的更多信息,请参阅 here .

关于c# - 如何确保 WCF 服务不会与数据库并行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56128728/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com