C# 如何使并行数据库按顺序更改?
我正在使用WebAPI和实体框架6开发一个项目 有一个控制器,其方法是向数据库添加新的实体任务。在添加任务之前,请为其计算唯一名称。名称的一部分基于数据库中已保存的任务。如果您发出两个并行请求,您可以生成相同的名称,这个问题通过锁解决 如果两台WebAPI服务器运行时连接到同一个数据库,如何防止生成相同的名称 是否可以在数据库级别将添加任务的算法添加到顺序队列中 简化代码:C# 如何使并行数据库按顺序更改?,c#,postgresql,asp.net-web-api,entity-framework-6,C#,Postgresql,Asp.net Web Api,Entity Framework 6,我正在使用WebAPI和实体框架6开发一个项目 有一个控制器,其方法是向数据库添加新的实体任务。在添加任务之前,请为其计算唯一名称。名称的一部分基于数据库中已保存的任务。如果您发出两个并行请求,您可以生成相同的名称,这个问题通过锁解决 如果两台WebAPI服务器运行时连接到同一个数据库,如何防止生成相同的名称 是否可以在数据库级别将添加任务的算法添加到顺序队列中 简化代码: [HttpPost] [Route("add")] public IHttpActionResul
[HttpPost]
[Route("add")]
public IHttpActionResult AddTask()
{
using (var db = CreateDbContext())
{
Task task = new Task();
lock (lockAdd)
{
DateTime dateTime = DateTime.UtcNow;
string preName = dateTime.ToString("yyMMdd-HHmm-");
var query = db.Tasks.Where(t => t.Name.StartsWith(preName)).Select(t => t.Name);
List<string> tasksNames = query.ToList();
task.Name = preName + (tasksNames.Count + 1).ToString("D4");
db.Tasks.Add(task);
db.SaveChanges();
}
return Ok();
}
}
С列名称不能唯一。
任务从未被删除。
对于每个新的日期和新的分钟,计数器必须从1开始。您应该使用序列在数据库端生成数据。在这种情况下,唯一性由数据库保证。
或者使用Guid UUID-它提供唯一的键。在这种情况下,通过UUID的思想来保证唯一性除了上面的答案之外,您还可以在C中生成Guid: 唯一性是有保证的,因为GUID同时包含服务器时间和服务器的MAC地址。还有一些长度较短的解决方案,例如像Snowflake这样的64位UUID生成器。有关C端口示例,请参阅: 或
注意:如果使用单例雪花生成器,则只需锁定ID生成器,因为同一毫秒内的增量计数器最多可保证2^12个ID/ms/server的唯一性。第二个源已经为此提供了一个锁。最简单的方法可能是将逻辑添加到数据库中,并从中返回值,可能是插入触发器。这样,它将始终得到妥善处理。否则,在插入相同名称时,您必须具有唯一索引并处理异常。计数器必须从1开始计算每个新日期新分钟计数器必须从1开始计算每个新日期新分钟。在这种情况下,您真正需要的不是应用程序锁,而是具有可序列化写入锁的事务: