|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
MSDTC, Transaction, Context and ThreadsI'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 Gian Paolo Clarici wrote:
Show quote > I've a problem using multithreading and MTS. Your threads have to be marked as MTA, multithreadedapartments. You've> 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? > any help will be apreciated! to check the ApartmentState of the thread objects. Still, I'm with you that it's unclear how to do this. Browsing through the docs I ran into quite a view inconsistencies, so I'm sorry but I can't give you a clear answer, other than that the threading model of your threads has to be MTA, not STA. FB -- ------------------------------------------------------------------------ Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com My .NET blog: http://weblogs.asp.net/fbouma Microsoft MVP (C#) ------------------------------------------------------------------------ |
|||||||||||||||||||||||