1

我在 .NET 3.5 中有一个自定义的数据导入可执行文件,SqlBulkCopy 基本上可以更快地插入大量数据。该应用程序基本上采用输入文件,处理数据并将其批量上传到 SQL Server 2000。它是由一位使用 SQL 2008 数据库环境构建它的顾问编写的。环境差异会导致这种情况吗?SQL 2000 确实具有 BulkCopy 所基于的 bcp 实用程序。所以,当我们运行它时,它触发了一个死锁错误。

错误详细信息:事务(进程 ID 58)与另一个进程在锁定资源上死锁,并已被选为死锁牺牲品。重新运行事务。

我已经尝试了很多方法来尝试解决它。比如临时设置连接字符串变量MultipleActiveResultSets=true,虽然不太理想,但还是会报死锁错误。我还确保这不是连接超时问题。

这是功能。有什么建议吗?

/// <summary>
    /// Bulks the insert.
    /// </summary>
    public void BulkInsert(string destinationTableName, DataTable dataTable)
    {
        SqlBulkCopy bulkCopy;

        if (this.Transaction != null)
        {
            bulkCopy = new SqlBulkCopy
                (
                    this.Connection,
                    SqlBulkCopyOptions.TableLock,
                    this.Transaction
                );
        }
        else
        {
            bulkCopy = new SqlBulkCopy
                (
                    this.Connection.ConnectionString,
                    SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction
                );
        }

        bulkCopy.ColumnMappings.Add("FeeScheduleID", "FeeScheduleID");
        bulkCopy.ColumnMappings.Add("ProcedureID", "ProcedureID");
        bulkCopy.ColumnMappings.Add("AltCode", "AltCode");
        bulkCopy.ColumnMappings.Add("AltDescription", "AltDescription");
        bulkCopy.ColumnMappings.Add("Fee", "Fee");
        bulkCopy.ColumnMappings.Add("Discount", "Discount");
        bulkCopy.ColumnMappings.Add("Comment", "Comment");
        bulkCopy.ColumnMappings.Add("Description", "Description");


        bulkCopy.BatchSize = dataTable.Rows.Count;
        bulkCopy.DestinationTableName = destinationTableName;
        bulkCopy.WriteToServer(dataTable);

        bulkCopy = null;
    }
4

4 回答 4

0

这些插入是同时进行的吗?在具有聚集索引的表上使用 TABLOCK 提示进行并发插入时,SqlBulkCopy 存在一个已知问题。它会导致发生死锁。请参阅以下内容:

http://msdn.microsoft.com/en-us/library/ms186341(SQL.90).aspx

于 2010-05-12T22:43:59.353 回答
0

我终于能够获得我们生产数据库的本地副本(约 50 个演出)来测试应用程序。事实证明,解除锁定严格来说是一个环境问题。谢谢各位。

于 2010-05-13T18:15:25.527 回答
0

我经常使用 BCP,而且我从未见过将 BatchSize 设置为典型值 1000 以外的任何值的情况。

此字段并非旨在表示代码中显示的整个行数,而是表示在复制期间要发送到服务器的可管理数据块,有点像 IP 数据包大小。

您可以尝试将此值更改为 1000 而不是整个表。

您可能还想查看 SQL Enterprise Manager 或 SQL Management Studio 中的进程/锁定管理器窗格(取决于您的客户端工具版本),并查看进程在锁定方面正在做什么。

于 2010-05-12T22:33:42.480 回答
0

多个活动结果集与插入无关——我什至不认为 SQL Server 2000 支持它,因为它是后来添加的。

SQL Server 2000 没有像更高版本那样复杂的锁升级——我希望这就是您所看到的。我假设顾问在目标表上没有 BCP 以外的工作负载,而您的应用程序在目标表上确实有除批量插入之外的活动。

我会考虑先将您的批量插入到临时表中(因此那里没有死锁的机会),然后在本机 SQL SP 中尽可能高效地插入/更新查询(可能在许多小批量中)。

于 2010-05-13T04:05:36.260 回答