views:

146

answers:

3

I'm busy building a software update application in C#, WinForms, .NET 3.5, where I have a collection of pluggable task classes with a common base class. I would like one task, the database upgrade, to begin a transaction, and another task, the web site upgrade, to commit or roll back the same transaction, so the web site and DB are always in sync.

I vaguely remember stuff from my VB6 days where a COM+ method could enlist in a transaction if one was already running, or begin one if not, etc. I also have vague memories of this porting to .NET Enterprise Services, but that was also a while ago.

What is the current technology to use to achieve this?

+3  A: 

You might want to start here.

http://msdn.microsoft.com/en-us/library/86773566.aspx

SqlConnection.BeginTransaction returns a SqlTransaction, which implements IDbTransaction.

The two methods defined on IDbTransaction are Commit() and Rollback(). If you keep the connection object alive between calls, you should be able to pass the transaction from one place to another and perform the commit or rollback there.

If you're not using SQL Server, your database provider (OleDb, Odbc, etc.) will provide a corresponding object.

harpo
+1  A: 

Off the top of my head, I think you should be able to do this w/o special technology. Create an UpgradeManager class that is responsible for kicking off both the database and web upgrades. The transaction should live here and be called surrounding the calls into the two other objects.

If you have other tasks to plug in, have the UpgradeManager iterate over a collection of your Tasks.

.....or you could pass the transaction around, like harpo said (his response came in the middle of composing mine)... good to have options. ;-)

Nate

Nathan Southerland
Thanks, I now have an idea of exposing transaction stuff to the task objects as a service in their container.
ProfK
+3  A: 

I think you are looking for environment transactions, or implicit transactions

using (TransactionScope scope = new TransactionScope())
{
   // do several stuff in the same transaction
   // calls in here implicitly are in the scope of the transaction.
   // you open several independent connections, which are in the same transaction.
}
Stefan Steinegger
Did you check this out?
Stefan Steinegger
+1 this is what transaction scope was designed for
Sam Saffron