Welcome to MSDN Blogs Sign in | Join | Help

Transactions made easy: System.Transactions

Currently in .Net Framework (v1.0 and v1.1) the support for transactions is offered by System.EnterpriseServices and by the System.Data.IDbTransaction, implemented by one of your favorite data provider (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconprocessingtransactions.asp?frame=true for more details). Both models have some disadvantages (the first is forcing the inheritance from ServicedComponent and the later offers support only for "local" transactions in that specific database) and together they don't provide a consistent and complete programming model. If all you need is to use a distributed transaction for protection when interacting with two or more resource managers, the only way to do it today is by taking a cumbersome road of using P/Invoke and COM Interop to access the "old and dusted" MSDTC APIs.

With the first beta preview of the next version of .Net Framework, codename Whidbey (available for download at http://lab.msdn.microsoft.com/vs2005/get/default.aspx ), the pain is over and transactions are here with a bright new and simple programming model, offering an exploding number of possibilities which can make your life simpler, safer and even faster. Please welcome System.Transactions [http://lab.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/N_System_Transactions.asp?frame=true]

The quick summary of the most important features offered by System.Transactions is: an easy to use programming model, support for transactional code blocks using TransactionScope, the concept of the "ambient" transaction using Transaction.Current, a super fast "lightweight" transaction manager for in appdomain transactions that involve at most a single durable resource manager, automatic promotion from "lightweight" to distributed transactions on a need basis and protection against early commits in an async environment using IDependentTransaction.

Over the next weeks I will go over each of these features, with code samples but for today, let me begin by telling you that all you need to get started is to understand the use of TransactionScope. Here is a small piece of code annotated with my explanations:

using System;
using System.Transactions;

namespace TxScopeSample
{
    class Program
    {
        static void Main(string[] args)
        {
         // create a new transaction scope and protect it 
         // inside an using statement against unexpected exceptions
         using (TransactionScope ts = new TransactionScope())
         {
            // do the transactional work
            // an "ambient" transaction is placed in the current call context
 
            // USER CODE: open connection to database 1
            // the data provider will detect the ambient transaction and automatically enlist into it
            // USER CODE: execute update in database 1 (for instance a credit operation)
 
            // USER CODE: open connection to database 2
            // the data provider will detect the ambient transaction and automatically enlist into it
            // USER CODE: execute update in database 2 (for instance a debit operation) // the following code will be executed only if no exception
            // occured in the above code; since we got here ok, let's vote for commit;
            // in most if not all of the cases, this last line will be the same as below
            ts.Complete(); // was ts.Consistent = true; in beta 2
         }          // when "using" will be  calling Dispose on the transaction scope at the end
         // of the "using" code block, the "ambient" transaction will be commited only and only if
         // the Complete method was called
      }
   }
}

The only code you need to fill in to get your scenarios running is for the lines marked with "USER CODE". And that is all!

When you get the chance to try System.Transactions, please use this blog entry to send me and my team your comments about it. Tell us what you like and what you don't like about this new programming model, we will certainly listen to your feedback. Thanks!

[UPDATE] In Beta 2, the Consistent flag was replaced with a Complete method. Calling TransactionScope.Complete() is equivalent with the statement "TransactionScope.Consistent = true;".

Published Friday, July 23, 2004 12:35 AM by florinlazar

Comments

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 1:01 AM by Sorin Dolha (MCSD .NET)
Very nice, I've been waiting for it for a long time! Good job!

# Whidbey and transactions

Friday, July 23, 2004 7:30 AM by Girish Bharadwaj

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 5:05 AM by Kyle Tinsley
This is awesome. Is TransactionScope also the way to handle single database (multi-table) transactions?

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 6:28 AM by Krishna
I tried out the code, the connection was against single SQL Server database but different tables, in code flow below, after Child Class 2 has set the TransactionConsistent option to false and calls a method in Child Class 3, if I put the code within a Transaction Scope, I get "Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction." if I don't put it in a Transaction Scope, I get "The transaction has already been implicitly or explicitly committed or aborted" If I set the TransactionConsitent bit to true, everything works fine..So how to handle these set of cases? I can send in the actual code in case you need them..

//Code flow

//Class 1
Using (TransactionScope1)
{
//Open Connection 1
//Create Child Class 1
}

//Child Class 1
Using (TransactionScope2)
{
//Open Connection 2
//User Code
//Set Transaction Consistent to false
//Create Child Class 2
}

//Child Class 2
{
//No Transaction Scope, just a read operation
//Open Connection <- Exception Thrown as "The transaction has already been implicitly or explicitly committed or aborted"

}

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 6:32 AM by Krishna
What about [Autocommit] and [TransactionOption] attributes similar to that of the support we have in EnterpriseServices. I remember seeing similar attributes in a presentation from the PDC on Distributed Transactions using the Light weight Transaction Manager.

We are currently using Remoting interception (derived from ContextBound and applied ContextAttributes) for Distributed Transactions without using EnterpriseServices. Since these classes are not documented and might become internal in future releases of the framework we want to move away from this model and use the System.Transaction classes instead, so we were comparing the options available and wanted to know if similar attributes would be made available in the future...basically we are looking for applying the "using TransctionScope" block through attributes and avoid having to write the plumbing code...

Thanks !

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 6:54 AM by Stuart
Simple transaction need that I can't figure out how to do it in 1.x *or* with new model:

I want transparent transactedness for all my ASP.NET pages. By which I mean, each page request should take place in its own transaction; if page load runs to completion with no exception (or terminates with the implicit ThreadAbortException thrown by Response.End, which is usually success in practice) the transaction is committed; otherwise (any other exception) it's rolled back. I'd also like to be able to access the transaction for rollback by hand, if there's an error condition that I want to handle some other way than by letting the exception propagate out.

I thought I could do that with a <%@ Page Transaction=something %> directive, but none of the available values of the Transaction attribute are, well, comprehensible to me at all. I tried a couple of the most likely-sounding candidates and ended up with the site completely screwed, giving an error even after I removed the transaction directive. I didn't try again after that; there are other developers working on the site too.

Even with the new transaction stuff described in your blog, I still can't figure out how I would implement this behavior. I can't use 'using' because there's nowhere to place the 'using' block such that its scope covers all of the page lifecycle. I'm sure I'm missing something obvious - like some documentation that makes sense? ;)

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 7:15 PM by Florin Lazar [MSFT]
TO: Kyle Tinsley
Yes, TransactionScope is also good for single-database transactions. In fact, when only one resource manager is used and this resource manager supports promotable transactions, there will be no overhead.

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 7:34 PM by Florin Lazar [MSFT]
To: Krishna

I have to see the code to give you an answer. You can send it to me by using the http://blogs.msdn.com/florinlazar/contact.aspx

One thing that you need to be careful is that it is not recommended to execute any code after you set the consistent flag inside a transaction scope. And in general, if you do set it to false, that means you are in a bad state and you want to abort everything as soon as possible, i.e. don't do any further work as part of that transaction because you know it will abort.

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 7:43 PM by Florin Lazar [MSFT]
To: Krishna 2nd comment

Currently there are no attributes for transactions as part of System.Transactions namespace. They are provided either by EnterpriseServices or will be by "Indigo" (these are the attributes you've seen at PDC). Or you can write your own attributes. Please, make sure to read my disclaimer.

# re: Transactions made easy: System.Transactions

Friday, July 23, 2004 7:53 PM by Florin Lazar [MSFT]
To: Stuart

Did you look at ContextUtil.SetAbort()? I believe this is what you are looking for.

See more info at http://samples.gotdotnet.com/quickstart/aspplus/doc/mtstransactions.aspx

# Using distributed transactions in .Net 1.x without deriving from ServicedComponent

Saturday, July 24, 2004 4:49 AM by Florin Lazar's WebLog

# Using distributed transactions in .Net 1.x without deriving from ServicedComponent

Saturday, July 24, 2004 2:57 PM by Florin Lazar's WebLog

# re: Transactions made easy: System.Transactions

Monday, July 26, 2004 7:20 AM by Krishna
Thanks Florin, I have submitted the code in the link provided..the subject is "System.Transactions Sample Code that throws Exception..See note on Blog" let me know if you need more information..

how to check the consistency of the transaction?..say a child class has set the transaction scope consistent flag to false..is it possible to check this in the parent class after the call to the child??..

on the note on Attributes..is there special attribute that we need to inherit from to make the transaction scopes transparent on a method or a class??

Thanks

# re: using - It's not just for memory management

Thursday, July 29, 2004 4:21 AM by Eric Gunnerson's C# Compendium

# System.Transactions in Whidbey

Friday, November 05, 2004 2:28 AM by Kevin Cunningham's Blog

# System.Transactions in Whidbey

Friday, November 05, 2004 1:44 PM by Kevin Cunningham's Blog

# Using distributed transactions in .Net 1.x without deriving from ServicedComponent

Wednesday, January 05, 2005 2:33 AM by xdev
Ping Back来自:blog.csdn.net

# Using distributed transactions in .Net 1.x without deriving from ServicedComponent

Wednesday, March 09, 2005 10:45 AM by coollzh
TrackBack From:http://www.cnblogs.com/coollzh/archive/2005/03/09/115813.html

# re: Transactions made easy: System.Transactions

Thursday, September 15, 2005 11:24 AM by Mike
Hey All,

Using Beta 2 of VS2005 and I'm attempting to use transaction scope in the business layer with no success. Seems to work ok on XP but when we run in a Windows 2003 environment, it fails with access denied.

Any ideas?
Mike

# re: Transactions made easy: System.Transactions

Tuesday, October 04, 2005 12:21 AM by florinlazar
To Mike: It's unusual to get an access denied. I don't know of any case when System.Transactions or DTC return "Access Denied". You should post more details about your scenario.

# re: Transactions made easy: System.Transactions

Wednesday, October 12, 2005 3:55 AM by hbzhang
When two connections opened in the same transactionscope, it triggers a DTC transaction, not a local transaction, even if two connections point to the same database. I use win2003 and sql2005 with .net 2.0 beta 2.

Is this behaviour as designed?

Thanks

# re: Transactions made easy: System.Transactions

Monday, November 21, 2005 4:25 AM by Jesús
I have the same trouble than Mike (see post on Thursday, September 15, 2005 11:24 AM) with the System.Transacions.

We are migrating code from Windows XP and VS2005 beta 2 to Windows Server 2003 and the VS2005 november release. We have the SQL Server in a different server and we are getting the exception message "The transaction has already been implicitly or explicitly committed or aborted".

The code is like this:

using (TransactionScope ts = new TransactionScope())
{
TableAdapter1 ta1 = new TableAdapter1();
TableAdapter2 ta2 = new TableAdapter2();
try
{
ta1.Update(dataset);
ta2.Update(dataset);
ts.Complete();
dataset.AcceptChanges();
return true;
}
catch
{
dataset.RejectChanges();
}
finally
{
ts.Dispose();
}
}

Thanks

# re: Transactions made easy: System.Transactions

Wednesday, January 11, 2006 11:23 AM by bogosian
for the TransactionScope - already committed/aborted one can read this very
useful article:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=124293&SiteId=1

bye, good luck

# re: Transactions made easy: System.Transactions

Tuesday, January 31, 2006 2:17 AM by florinlazar
To: hbzhang

The behavior is currently by design. The WebData/ADO team may be able to optimize this in the future if we (me and you) ask them nicely :)

# re: Transactions made easy: System.Transactions

Tuesday, January 31, 2006 2:24 AM by florinlazar
To: Jesús

Shouldn't you put ts.Complete() after dataset.AcceptChanges? I'm not sure what AcceptChanges does, but if is trying to use the current transaction, that might explain why you are getting the exception.

# re: Transactions made easy: System.Transactions

Friday, April 28, 2006 3:29 AM by Ashish
To : Jesus, Why are u doing ts.Dispose? You are already using "using".

# re: Transactions made easy: System.Transactions

Monday, May 01, 2006 10:04 PM by BKimball
What version of Visual Studio 2005 is needed for the transactional support, or am I just really lost here? I put in using System.Transactions; (Well tried to, doesn't show up in intellisense) but am unable to access anything in the namespace. Was this dropped from the final release of VS2K5 or do I need something better than Standard Edition?

# re: Transactions made easy: System.Transactions

Thursday, July 20, 2006 12:54 AM by Sundar Paranthaman
I am using TransactionScope object to achieve transaction support across 2 components that could have database interactions. Both components make connections to the database and change data. Even though both components connect to the same database with the same connection string, when the second connection is made the transaction escalates to a Distributed Transaction. Is it possible to change this behavior so that the transaction doesn’t escalate since the connections are to the same database with the same connection string. The main reason I want to prevent transaction escalation is our product has to work in WindowsXPSP2 and DTC service is disabled by default.

# re: Transactions made easy: System.Transactions

Tuesday, September 12, 2006 2:25 AM by David
I am geting Transaction aborted Execption, i am using sql Server 2000. using (TransactionScope scope = new TransactionScope() { Store_to_database(int vl,int v2) scope.Complete(); } In the Store_to_database function i am opening a connection to database, inserting the record. but i m geting Execption "The Transaction has Aborted" on connection.open() statement. please Help me.....

# re: Transactions made easy: System.Transactions

Tuesday, October 03, 2006 9:17 PM by florinlazar

To: Sundar Paranthaman

I recommend looking at the ConnectionScope class from

http://blogs.msdn.com/dataaccess/archive/2006/02/14/532026.aspx

# re: Transactions made easy: System.Transactions

Wednesday, February 21, 2007 3:40 PM by Dan

To use TransactionScope what needs to be installed and running on Windows 2000 or Windows 2003 server & SQL 2000?

Thanks.

# re: Transactions made easy: System.Transactions

Wednesday, February 21, 2007 10:22 PM by florinlazar

To: Dan

You need to install .Net Framework 2.0 or higher in order to be able to use System.Transactions.

# re: Transactions made easy: System.Transactions

Monday, February 26, 2007 10:14 AM by Khurram

Hi I am having the same error. In our case the application is on win server 2003 and the sql server on win2k. Do we need to install .NET framework 2 on both servers SQL and Web?

# re: Transactions made easy: System.Transactions

Wednesday, February 28, 2007 2:29 PM by florinlazar

# Lexapro side effects.

Friday, July 18, 2008 9:48 PM by Lexapro when does it work.

Lexapro. Side effects lexapro.

# Propecia finasteride.

Monday, July 28, 2008 12:52 AM by Propecia side effects bad.

Hair loss propecia drug dht. Propecia. Generic propecia. Propecia generic.

Anonymous comments are disabled
 
Page view tracker