Command Object and the Transactional(TransactionalTypes.TransactionScope) attribute

Command Object and the Transactional(TransactionalTypes.TransactionScope) attribute

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


mikeclimbs posted on Friday, May 02, 2008

I'm using sql server 2005 and csla 2.1

I have a command object used for creating and saving checks.  it can create anywhere from 1 to xxxx checks.  if any of the checks fail to save I want to rollback all checks.

I added Transactional(TransactionalTypes.TransactionScope) to the

DataPortal_Execute() of my command object.  It is not rolling back the saved items.

any help would be appreciated.

 The command obj and bizobject DataPortal_Insert() is below:

 <Transactional(TransactionalTypes.TransactionScope)> _

Protected Overrides Sub DataPortal_Execute()

Try

Dim tr As SqlTransaction

Using cn As SqlConnection = New SqlConnection(connectionstr)

cn.Open()

tr = cn.BeginTransaction()

Try

for each invoice in invoicelist

create and init bizobj

   bizobj.save

next

tr.commit

Result = True

Catch

Result = False

tr.Rollback()

End Try

End Using

 

Protected Overrides Sub DataPortal_Insert()

Dim tr As SqlTransaction

Using cn As SqlConnection = New SqlConnection(FUNDEZConnection)

cn.Open()

tr = cn.BeginTransaction()

Try

ExecuteInsert(tr)

'update child object(s)

UpdateChildren(tr)

tr.Commit()

Catch

tr.Rollback()

Throw

End Try

End Using

End Sub

sergeyb replied on Friday, May 02, 2008

Just a thought…  Your command’s data portal is creating objects, and calling Save, thus making another data portal call.  Did you make sure your config file on the server does not have data portal section?  On a side note, I typically create friend method in Invoice class and call it, passing transaction explicitly.  For example:

In invoice object I have

 

Friend Shared Sub Update(transaction as SQLTrsanaction)

                ExecuteInsert(transaction)

                UpdateChildren(transaction)

End Sub 

 

In Command_Execute

Create objects

Create transaction

Invoice.Update(transaction)

 

Having said that, your code should rollback properly, although I generally prefer to pass transaction object explicitly to avoid even possibility of using DTC.  This is just me though.

 

Sergey Barskiy

Senior Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: mikeclimbs [mailto:cslanet@lhotka.net]
Sent: Friday, May 02, 2008 3:00 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Command Object and the Transactional(TransactionalTypes.TransactionScope) attribute

 

I'm using sql server 2005 and csla 2.1

I have a command object used for creating and saving checks.  it can create anywhere from 1 to xxxx checks.  if any of the checks fail to save I want to rollback all checks.

I added Transactional(TransactionalTypes.TransactionScope) to the

DataPortal_Execute() of my command object.  It is not rolling back the saved items.

any help would be appreciated.

 The command obj and bizobject DataPortal_Insert() is below:

 <Transactional(TransactionalTypes.TransactionScope)> _

Protected Overrides Sub DataPortal_Execute()

Try

Dim tr As SqlTransaction

Using cn As SqlConnection = New SqlConnection(connectionstr)

cn.Open()

tr = cn.BeginTransaction()

Try

for each invoice in invoicelist

create and init bizobj

   bizobj.save

next

tr.commit

Result = True

Catch

Result = False

tr.Rollback()

End Try

End Using

 

Protected Overrides Sub DataPortal_Insert()

Dim tr As SqlTransaction

Using cn As SqlConnection = New SqlConnection(FUNDEZConnection)

cn.Open()

tr = cn.BeginTransaction()

Try

ExecuteInsert(tr)

'update child object(s)

UpdateChildren(tr)

tr.Commit()

Catch

tr.Rollback()

Throw

End Try

End Using

End Sub



mikeclimbs replied on Friday, May 02, 2008

oops, forgot to mention I'm running in local mode

sergeyb replied on Friday, May 02, 2008

And DTC is running on your machine?

 

Sergey Barskiy

Senior Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: mikeclimbs [mailto:cslanet@lhotka.net]
Sent: Friday, May 02, 2008 3:18 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] Command Object and the Transactional(TransactionalTypes.TransactionScope) attribute

 

oops, forgot to mention I'm running in local mode

mikeclimbs replied on Friday, May 02, 2008

Sergey thanks for your help.

I don't think I'm running DTC.  Do I need to be?

Do you think changing my bizobject dataportal insert so its uses a shared connection will help?

sergeyb replied on Friday, May 02, 2008

Yes, if you pass transaction around, you will not need DTC to enforce transactions.  Otherwise, you do need to run DTC in your case.  The rule is that if you use one connection in SQL Server, you do not need DTC.  If you search forum, you will find some more discussions on the DTC usage.  I usually opt to not rely on DTC in my design.  So, the pattern that I follow is:

 

In root objects’ DataPortal_XXX

 

Create transaction

Try

Call Friend Methods of each child:  aChild.Update(transaction)

Transcation.Commit

Catch

Transaction.Rollback

Throw

End Try

 

 

 

Sergey Barskiy

Senior Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: mikeclimbs [mailto:cslanet@lhotka.net]
Sent: Friday, May 02, 2008 3:39 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Command Object and the Transactional(TransactionalTypes.TransactionScope) attribute

 

Sergey thanks for your help.

I don't think I'm running DTC.  Do I need to be?

Do you think changing my bizobject dataportal insert so its uses a shared connection will help?



mikeclimbs replied on Monday, May 05, 2008

Sergey,

Again thanks for you help.  guess its time to look into enaling dts.

 

Mike

RockfordLhotka replied on Monday, May 05, 2008

You can also use the Csla.ApplicationContext.LocalContext technique shown in the CSLA .NET Version 2.1 Handbook to (relatively) easily pass a connection/transaction object to all your objects.

Or better still, use the Csla.Data.ConnectionManager class in CSLA .NET 3.5 to manage your connection object so you get automatic reuse and typically avoid needing the DTC.

ConnectionManager should be pretty easy to back-port to CSLA 2.0/3.0 if necessary.

Copyright (c) Marimer LLC