如何让 TransactionScope 处理大型 sql 事务?

How to get TransactionScope to work on large sql transactions?

我有一个应用程序需要写入 sql 数据库上的 table。 sql 字符串的 IN 语句中使用的 ID 需要分块,因为 IN 中可能有 300k 个 ID,这会溢出 Web 配置中的最大字符串长度。当我尝试使用 200+k ID 测试场景而不是大约 50K ID 时出现此错误:

与当前连接关联的事务已完成但尚未处理。必须先处理事务,然后才能使用连接执行 SQL 语句。

代码如下:

    public int? MatchReconDetail(int ReconRuleNameID, List<int> participants, int? matchID, string userID, int FiscalPeriodID)
    {
                DataContext context = new DataContext();
        context.CommandTimeout = 600;



            using (TransactionScope transaction = new TransactionScope())
            {

                Match dbMatch = new Match() { AppUserIDMatchedBy = userID, FiscalPeriodID = FiscalPeriodID, DateCreated = DateTime.Now };
                context.Matches.InsertOnSubmit(dbMatch);
                context.SubmitChanges();

                //string ids = string.Concat(participants.Select(rid => string.Format("{0}, ", rid))).TrimEnd(new char[] { ' ', ',' });

                int listCount = participants.Count;
                int listChunk = listCount / 1000;
                int count = 0;
                int countLimit = 1000;


                    for (int x = 0; x <= listChunk; x++)
                    {

                        count = 1000 * x;
                        countLimit = 1000 * (x + 1);
                        List<string> chunkList = new List<string>();

                        for (int i = count; i < countLimit; i++)
                        {
                            if (listCount - count < 1000 && listCount - count != 0)
                            {
                                int remainder = listCount - count;

                                for (int r = 0; r < remainder; r++)
                                {
                                    chunkList.Add(participants[count].ToString());
                                    count++;
                                }

                            }
                            else if (listCount - count >= 1000)
                            {
                                chunkList.Add(participants[i].ToString());
                            }

                        }

                        string ids = string.Concat(chunkList.Select(rid => string.Format("{0}, ", rid))).TrimEnd(new char[] { ' ', ',' });

                        string sqlMatch = string.Format("UPDATE [Cars3]..[ReconDetail] SET [MatchID] = {0} WHERE [ID] IN ({1})", dbMatch.ID, ids);

                        context.ExecuteCommand(sqlMatch);

                    }

                matchID = dbMatch.ID;

                context.udpUpdateSummaryCache(FiscalPeriodID, ReconRuleNameID, false);

                transaction.Complete();
            }

            return matchID;
        }
    }

我已经阅读了一些建议超时问题的文章,因此我在此函数的顶部添加了 context.CommandTimeout。该错误似乎是在事件触发后大约一分钟后发生的。

如有任何想法,我们将不胜感激。

您也需要设置交易超时时间。不仅是命令。

您可能还必须修改最大事务超时。默认为 10 分钟,可以在 machine.config 文件中更改。

阅读 this blog post 了解更多详情。

我使用以下方法解决了这个问题:

    using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0,30,0)))