SQL query in Parallel.ForEach - Deadlock
I have a static method which calls SQL SP inside a static method in a Parallel.ForEach l开发者_Python百科oop. SP inserts data in 3 different tables. I am using Serializable Transaction level. But once in a while i am running into Deadlock situation.
I am thinking that if i make that method as Instance method or use simple ForEach, it may fix the problem.
Am i thinking right? Do i need to lock the list as well?
--Code--
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();
}
}
}
}
Try to change your classes to non static methods that will help a lot. NEVER use statics in parallel it is just asking for trouble. And for safety try to use a thread save list aka an syncronized arraylist or a System.Collections.Concurrent.ConcurrentQueue(Of T)
.
Kind regards
You get problems because you do not use any synchronization. The keyword static
does not mean it is thread safe. Multiple threads from Parallel.ForEach
can still access this method at the same time.
You have many options to synch that. But I will start with the easiest one, make it single threaded. If not possible, use lock
or see other options
UPDATE
As noticed by @Colin, my answer works if you update the data somewhere. If everything is read-only, there is something else then. Check creation of the DataTable.
精彩评论