Question for TransactionScope

Question for TransactionScope

Old forum URL: forums.lhotka.net/forums/t/804.aspx


Brian Tian posted on Thursday, August 03, 2006

Hi, All,

I use the TransactionScope for updaing a collection object. But all the children objects before the bad one will be saved, it won't rollback the whole transaction. Do I miss something? Here is the snippet codes.

In our suitation, the collection won't have parent base object. We must directly deal with the collection object. In the collection object, I create a public function Update( ) and try to call the DataPortal_Update() by using transactionScope.

public void Update
{
      DataPortal_Update();
}

[Csla.Transactional(Csla.TransactionalTypes.TransactionScope)]
protected override void DataPortal_Update()
{
   this.RaiseListChangedEvents = false;
   using (SqlConnection cn = new SqlConnection(Database.ShowSupportConnection))
   {
         cn.Open();
         using (SqlCommand cm = cn.CreateCommand())   
         {
               //.......

               foreach (ChildObject obj in this)
               {
                     if (obj.IsNew)
                        obj.Insert(cn);
                     
else
                           
obj.Update(cn );
               
}
         }
      }
   this.RaiseListChangedEvents = true;
}

In the Child Object,  it calls Insert( )

internal void Insert( SqlConnection cn) 
{
   if (!this.IsDirty)
         return;
   using (SqlCommand cm = cn.CreateCommand())
   {
         cm.CommandType = CommandType.StoredProcedure;
         cm.CommandText = "usp_InsertSp";
         ...........// .....
   
         cm.ExecuteNonQuery();
         MarkOld();
   }
//using SqlCommand
}

 

The usp_InsertSp is used to insert several tables and update one table. Also, I don't have transaction commit and rollback setting in the stored procedure.

What do I miss? Thanks for your help

 

Brain Tian

ajj3085 replied on Thursday, August 03, 2006

That's very odd... I use transaction scope, and it works as expected.  I don't see anything wrong with your code either...

Brian Tian replied on Thursday, August 03, 2006

Hi, Ajj3085

Thanks for your quick response.

In our situation for this case, we don't have root object, we only have the collection object. So, it will loop the collection and save the children object one by one.  If one child failed, the chilren objects before this one will be saved. Is this because of I don't have root object?

Brian Tian

ajj3085 replied on Friday, August 04, 2006

Ahh, well that would certainly be a problem.  It looked like your root object was the collection itself though?  What you should do is implement a DataPortal method on the collection, and mark THAT as TransactionScope.  Then the whole collection commits or rollsback as a unit.

So make your collection as a root object, since a root object defines what must be commited as a single unit.

Brian Criswell replied on Friday, August 04, 2006

ajj3085:
Ahh, well that would certainly be a problem.  It looked like your root object was the collection itself though?  What you should do is implement a DataPortal method on the collection, and mark THAT as TransactionScope.  Then the whole collection commits or rollsback as a unit.

So make your collection as a root object, since a root object defines what must be commited as a single unit.


That is what he arrived at by the end of the thread.

ajj3085 replied on Friday, August 04, 2006

Yes, I should really have finished reading this thread before replying. Smile [:)]

Brian Criswell replied on Thursday, August 03, 2006

The problem is that you did not go through the DataPortal.  The DataPortal will read the transaction scope attribute and properly set up the TransactionScope.  Remove the Update() method and call Save(). instead.

Brian Tian replied on Thursday, August 03, 2006

Brian,

I use the Save( ) to instead of Update( ). I get error message "Can not directly save a child object" and this is because I don't have root object. I think there should be a way to take care of this case but I don't know how :-)

Thanks

Brian Criswell replied on Thursday, August 03, 2006

Is your collection calling MarkChild() anywhere?  It should not since you have described it as a root collection.

Brian Tian replied on Thursday, August 03, 2006

Brian Criswell.

You are right, I have MarkChild( ) because I created this collection using copy/paste. :-)  Now, It works

Thank you and have a good one.

Copyright (c) Marimer LLC