C# 异步数据库插入操作的顺序ID生成

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(() =>

这是我面临的一个典型问题。 我想使用异步TPL在数据库中插入2k行,其中每条记录都有一个增量顺序键。

            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。无法说出它是什么,因为缺少代码。