G
Gian Paolo Clarici
I've a problem using multithreading and MTS.
I'm using framework 1.1
Basically I want, from the Main Thread , to start a (distributed)
transaction.
then I want to start 2 new threads to perform some Database operations, each
thread will do some work on the DB using its own SQLConnection.
I want the 2 SQLConnections of the two threads partecipate to the same
(distributed) transaction.
The problem is that i do not know how to propagate the Object Context from
the Main thread to the 2 subThreads.
I start a new Transactional Context from the Main Thread with the following
code:
sc = new ServiceConfig();
sc.Transaction = TransactionOption.Required;
ServiceDomain.Enter(sc);
Then I run two Threads that will open two distinct SQLConnections
to perform some work at the same time .
ClasseTest CTest1 = new ClasseChiamata.ClasseTest() ;
ClasseTest CTest2 = new ClasseChiamata.ClasseTest() ;
Thread workThread1 = new Thread (new ThreadStart(CTest1.EseguiOp));
workThread1.Start();
Thread workThread2 = new Thread (new ThreadStart(CTest2.EseguiOp));
workThread2.Start();
workThread1.Join();
workThread2.Join();
The problem is that the SQLConnection created inside the method:
CTest2.EseguiOp()
is not automatically enlisted in the (Distributed)Transaction created before
the methods have been invoked asynchronously.
All works fine if I invoke the method synchronously, while if I use
multithreading to recall
the same method, the MTS object Context is not available to the subThreads.
Do you know how to pass the MTS Context to the 2 subThreads?
this is the code of the method that I want to recall asynchronously:
using System;
using System.Data;
using System.EnterpriseServices;
using System.Data.SqlClient;
namespace ClasseChiamata
{
public class ClasseTest
{
public bool hasError = false;
private SqlConnection mySqlConnection;
public ClasseTest()
{
}
public void EseguiOp()
{
try
{
mySqlConnection = new SqlConnection
("database=TEST;server=localhost;Persist Security
Info=False;uid=sa;pwd=xxxx");
SqlCommand mySqlCommand = new SqlCommand();
mySqlConnection.Open();
//mySqlConnection.EnlistDistributedTransaction(trans);
mySqlCommand.Connection = mySqlConnection;
mySqlCommand.CommandText = "UPDATE Table1 SET Description = 'AAA' WHERE
Code = 'A1'";
mySqlCommand.ExecuteNonQuery();
ContextUtil.SetAbort(); // this will work in synchronous mode, but will
fail if recalled in a secondary thread, with the error "there is no MTS
object Context"!
}
catch(System.Exception ex)
{
hasErrore = true;
}
}
}
}
the line that fails is the
ContextUtil.SetAbort(); // this will work in synchronous mode, but will
fail if recalled in a secondary thread, with the error "there is no MTS
object Context"!
any help will be apreciated!
JPC
I'm using framework 1.1
Basically I want, from the Main Thread , to start a (distributed)
transaction.
then I want to start 2 new threads to perform some Database operations, each
thread will do some work on the DB using its own SQLConnection.
I want the 2 SQLConnections of the two threads partecipate to the same
(distributed) transaction.
The problem is that i do not know how to propagate the Object Context from
the Main thread to the 2 subThreads.
I start a new Transactional Context from the Main Thread with the following
code:
sc = new ServiceConfig();
sc.Transaction = TransactionOption.Required;
ServiceDomain.Enter(sc);
Then I run two Threads that will open two distinct SQLConnections
to perform some work at the same time .
ClasseTest CTest1 = new ClasseChiamata.ClasseTest() ;
ClasseTest CTest2 = new ClasseChiamata.ClasseTest() ;
Thread workThread1 = new Thread (new ThreadStart(CTest1.EseguiOp));
workThread1.Start();
Thread workThread2 = new Thread (new ThreadStart(CTest2.EseguiOp));
workThread2.Start();
workThread1.Join();
workThread2.Join();
The problem is that the SQLConnection created inside the method:
CTest2.EseguiOp()
is not automatically enlisted in the (Distributed)Transaction created before
the methods have been invoked asynchronously.
All works fine if I invoke the method synchronously, while if I use
multithreading to recall
the same method, the MTS object Context is not available to the subThreads.
Do you know how to pass the MTS Context to the 2 subThreads?
this is the code of the method that I want to recall asynchronously:
using System;
using System.Data;
using System.EnterpriseServices;
using System.Data.SqlClient;
namespace ClasseChiamata
{
public class ClasseTest
{
public bool hasError = false;
private SqlConnection mySqlConnection;
public ClasseTest()
{
}
public void EseguiOp()
{
try
{
mySqlConnection = new SqlConnection
("database=TEST;server=localhost;Persist Security
Info=False;uid=sa;pwd=xxxx");
SqlCommand mySqlCommand = new SqlCommand();
mySqlConnection.Open();
//mySqlConnection.EnlistDistributedTransaction(trans);
mySqlCommand.Connection = mySqlConnection;
mySqlCommand.CommandText = "UPDATE Table1 SET Description = 'AAA' WHERE
Code = 'A1'";
mySqlCommand.ExecuteNonQuery();
ContextUtil.SetAbort(); // this will work in synchronous mode, but will
fail if recalled in a secondary thread, with the error "there is no MTS
object Context"!
}
catch(System.Exception ex)
{
hasErrore = true;
}
}
}
}
the line that fails is the
ContextUtil.SetAbort(); // this will work in synchronous mode, but will
fail if recalled in a secondary thread, with the error "there is no MTS
object Context"!
any help will be apreciated!
JPC