У меня есть статический метод, который вызывает SQL SP внутри статического метода в цикле Parallel.ForEach. SP вставляет данные в 3 разные таблицы. Я использую уровень сериализуемых транзакций. Но время от времени я попадаю в тупиковую ситуацию.
Я думаю, что если я сделаю этот метод методом экземпляра или воспользуюсь простым ForEach, это может решить проблему.
Я правильно думаю? Мне тоже нужно заблокировать список?
--Код--
Parallel.ForEach(MyConcurrentDictionary, MyElement =>
{
if (MyElement.SomeProperty != SomeValue)
{
PublishMessage(MyElement);
}
else
{
InsertInDatabase(MyElement);
}
}
public static void InsertInDatabase()
{
DataTable t1 = new DataTable();
DataTable t2 = new DataTable();
DataTable t3 = new DataTable();
CreateTable(T1);
CreateTable(T2);
CreateTable(T3);
using (var conn = new SqlConnection(ConnString))
{
try
{
conn.Open();
// Begin transaction
using (SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.Serializable))
{
SqlCommand cmd = new SqlCommand();
cmd.Transaction = transaction;
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SPName";
cmd.Parameters.AddWithValue("@T1", T1);
cmd.Parameters.AddWithValue("@T2", T2);
cmd.Parameters.AddWithValue("@T3", T3);
cmd.ExecuteNonQuery();
transaction.Commit();
}
}
}
}
IsolationLevel.Serializable
ЗЛО !!! Это наиболее требовательная настройка блокировки, которую вы можете получить. Вы уверены, что хотите этого? Я сомневаюсь, что вы это сделаете ... Serializable в Sql Server очень быстро перерастет блокировки в блокировки диапазона и таблицы. Если у вас есть какая-то пропускная способность, обязательно возникнут тупиковые ситуации.ReadCommitted
- это то, что вы ищете, и это уровень изоляции по умолчанию на сервере Sql,Serializable
- это уровень по умолчанию в .Net. - person Didaxis   schedule 07.10.2013