テーブルにデータを一括挿入するには、次の方法があります。まず、私のコードはデータテーブルにデータを入力し、.netのSqlBulkCopy句を使用して、このデータを対応するテーブルに挿入します。
データをすべてのテーブルに挿入するか、どちらにも挿入しないようにする必要があります。このために、私は.netのSqlTransactionクラスを使用しました。
シナリオは、複数のスレッドが同時に次のコードブロックを実行することです。
public void Import()
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
SqlTransaction sqlTrans =null;
try
{
sqlConnection.Open();
sqlTrans = sqlConnection.BeginTransaction(IsolationLevel.Serializable)
SqlCommand cmd = sqlConnection.CreateCommand();
cmd.CommandText = "select top 1 null from lockTable with(xlock)";
cmd.CommandTimeout = 3600*3;
cmd.Transaction = sqlTrans;
SqlDataReader reader = cmd.ExecuteReader();
foreach (DataTable dt in DataTables)
{
ImportIntoDatabase(sqlConnection, dt, sqlTrans);
}
reader.Close();
sqlTrans.Commit();
}
catch (Exception ex)
{
sqlTrans.Rollback();
throw ex;
}
}
}
private void ImportIntoDatabase(SqlConnection sqlConn, DataTable dt, SqlTransaction sqlTrans)
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.Default, sqlTrans))
{
bulkCopy.BulkCopyTimeout = dt.Rows.Count * 10;
try
{
bulkCopy.DestinationTableName = dt.TableName;
bulkCopy.WriteToServer(dt);
}
catch (Exception ex)
{
throw ex;
}
}
}
この同時実行性を処理するために、もう1つのテーブル(一括挿入テーブル)が存在するデータベースに1つのダミーテーブル(「lockTable」という名前のテーブル)を作成しました。SqlTransactionのこのダミーテーブルで排他ロックが発生し、コマンドタイムアウトが3時間になります。
問題:次の例外が発生します
:宛先テーブル'Tbl1'にアクセスできません(tbl1は一括挿入用のテーブルです)
キャッチブロックでトランザクションをロールバックしている間、別の例外が続きます
:アクティビティの実行中にエラーが発生しましたサーバーはトランザクションを再開できませんでした。Desc:3a00000001。このセッションでアクティブなトランザクションは、別のセッションによってコミットまたは中止されました。
コードのこの奇妙な振る舞いについて誰かが私を助けてくれますか?私はすでにインターネットでこの問題についてたくさん検索しましたが、私にとって役立つものは何も見つかりませんでした。