C# 异步数据库插入操作的顺序ID生成
这是我面临的一个典型问题。 我想使用异步TPL在数据库中插入2k行,其中每条记录都有一个增量顺序键。C# 异步数据库插入操作的顺序ID生成,c#,asynchronous,foreach,task-parallel-library,C#,Asynchronous,Foreach,Task Parallel Library,这是我面临的一个典型问题。 我想使用异步TPL在数据库中插入2k行,其中每条记录都有一个增量顺序键。 foreach (var grpMem in input.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList) { try { Task.Run(() =>
foreach (var grpMem in input.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList)
{
try
{
Task.Run(() => gd.insertGroupMembershipUploadDetails(grpMem,
input.ListChapterUploadFileDetailsInput, ++Max_seq_key, ++Max_grp_seq_key, Lst_com_unit_key, trans_key));
}
我的服务端有3层:
以下是:
服务端:
首先,我从数据库中获取max seq密钥
Data.Upload.UploadDetails gd = new Data.Upload.UploadDetails();
try
{
var Max_seq_key = gd.getGroupMembershipSeqKeyDetails();
此getGroupMembershipSeqKeyDetails方法位于DAL层中,如下所示:
public long getGroupMembershipSeqKeyDetails()
{
Repository rep = new Repository();
string strSPQuery = string.Empty;
List<long> listSeqKey = new List<long>();
long strMaxSeqKey = -1;
try
{
listSeqKey = rep.ExecuteSqlQuery<Int64>(SQL.Upload.UploadDetails.getMaxSeqKeySQL()).ToList();
strMaxSeqKey = listSeqKey[0] != null ? listSeqKey[0] : strMaxSeqKey;
return strMaxSeqKey;
}
catch (Exception e)
{
return strMaxSeqKey;
}
}
但是这个++Max_seq_键并不总是有保证的
有时我会得到类似于数据库中的结果:
我如何确保这个递增的seq键总是比上一个插入的记录(当然是在另一个线程上运行的记录)大1
如何确保此增量seq键始终大于1
显而易见的答案是“不要在客户端生成密钥”。忘了
max+1
方法吧
使用数据库功能生成唯一的键,如列或键
链接是特定于MS SQL的,但是您可以很容易地找到另一个RDBMS的相同文档,例如,这里有一个
另外,您的“异步”代码不是真正的异步-必须以异步方式重写存储库
如何确保此增量seq键始终大于1
显而易见的答案是“不要在客户端生成密钥”。忘了
max+1
方法吧
使用数据库功能生成唯一的键,如列或键
链接是特定于MS SQL的,但是您可以很容易地找到另一个RDBMS的相同文档,例如,这里有一个
另外,您的“异步”代码不是真正的异步代码-必须以异步方式重写存储库。正如Dennis的回答所述,最好是让数据库生成每个数字。但是对于
++
:这是一个已知的误解,认为这是一个线程安全的操作,但它不是原子的,因此不是线程安全的。对于线程安全增量,可以使用联锁。增量getMaxSeqKeySQL
有一个bug。因为代码缺失,所以无法说出它是什么。正如丹尼斯的回答所述,最好是让数据库生成每个数字。但是对于++
:这是一个已知的误解,认为这是一个线程安全的操作,但它不是原子的,因此不是线程安全的。对于线程安全增量,可以使用联锁。增量getMaxSeqKeySQL
有一个bug。无法说出它是什么,因为缺少代码。