[英]Cant insert into Identity Column when Multithreading
我有一個數據遷移工具,直到最近看起來還不錯。
我使用Parallel.Foreach遍歷數據行的集合,計算一些要插入到表的新記錄中的變量,然后運行SQL語句以插入數據。
Parallel.ForEach<DataRow>(dataTable.Rows, row =>
{
string reference = row["ref"].ToString();
int version = (int)row["version"];
string insertStatement = "INSERT INTO Item (Reference, Version) VALUES (@reference, @version)";
_database.ExecuteCommand(insertStatement, new SqlServerCeParameter[]
{
new SqlServerCeParameter("@reference", reference, SqlDbType.NVarChar),
new SqlServerCeParameter("@version", version, SqlDbType.Int),
});
});
public void ExecuteCommand(string sql, SqlServerCeParameter[] parameters)
{
//create the command that will execute the Sql
using (var command = new SqlCeCommand(sql, _connection))
{
//add any parameters
if (parameters != null) command.Parameters.AddRange(parameters.Select(p => p.ParameterBehind).ToArray());
try
{
//open the connection
if (_connection.State == ConnectionState.Closed) _connection.Open();
//execute the command
command.ExecuteNonQuery();
}
catch (SqlCeException ex)
{
//only catch if the native error is the duplicate value exception otherwise throw as normal
if (ex.NativeError != 25016) throw;
}
finally
{
//explicitly close command
command.Dispose();
}
}
}
但是我得到一個聚合異常,其內部異常如下:
{"The column cannot contain null values. [ Column name = ID,Table name = Item ]"}
該表的結構如下:
CREATE TABLE Item
(
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Reference NVARCHAR(50) NOT NULL,
Version INT NOT NULL
);
現在我不明白該錯誤,因為ID是一個身份列。
我曾經以為是因為多線程它不能同時計算兩個id,但這似乎是一個脆弱的原因,因為SqlServerCe對於多用戶環境是可以的。
重要說明: SQL CE對象不是線程安全的。 您在每個調用中都使用_connection
,我猜這是SqlCeConnection
的單個實例?
建議每個線程應使用自己的獨立連接,而不是在多個線程之間共享它。 因此,嘗試在ExecuteCommand
方法中創建一個新的SqlCeConnection
並每次進行連接。
這可能無法實現您希望/期望的速度提高,但是我不確定多線程是否如您期望的那樣工作。 您需要多個內核/處理器才能使其有效,並且本身就是一個深層的話題。
確保該表的IDENTITY_INSERT為ON。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.