Click here to Skip to main content
12,451,093 members (54,511 online)
Click here to Skip to main content
Add your own
alternative version

Stats

83K views
35 bookmarked
Posted

TransactionScope in .NET 1.1

, 1 Jun 2005
Rate this:
Please Sign up or sign in to vote.
Emulate TransactionScope functionality coming in .NET 2.0 with .NET 1.1.

Now: Declarative Database Transactions With ServicedComponent

Developers working with Microsoft SQL Server enjoyed declarative handling of transactions since Windows NT 4.0 days. With the .NET Framework, this usually means we need to inherit a class from ServicedComponent, apply TransactionAttribute to it, and use SetAbort/SetComplete methods to notify the framework if our DB operation succeeded or failed. The framework takes care of the rest.

Simple? Yes, but…

  • ServicedComponent requires you to sign your assemblies, the step considered by many developers as the unnecessary complication.
  • You can’t mix transactional and non-transactional methods in one class, which forces you to split a single logical CustomerService into CustomerReader and CustomerWriter or something like that.

Future: TransactionScope in .NET 2.0

In .NET 2.0, we are going to have the TransactionScope class which solves both problems. Used as braces around a code which must run inside a database transaction and, although not the declarative style anymore, it provides a nice clean model:

using (TransactionScope scope = new TransactionScope())
{
  // open connection
  // perform database operation, which is going to run inside the transaction
// call other method and if the other method creates a TransactionScope object
  // it will share the transaction with the current method

  // All is well:
  Scope.Complete();
}

The Future's Here

OK, the code above looks as good as I’d like it to be, but Whidbey isn’t coming to production machines near me for another year or so. I had to create my own solution using .NET 1.1, and here it is. In fact, the implementation is so embarrassingly simple that I now feel ashamed I didn’t figure it out earlier!

Usage:

using (TransactionScope scope = new TransactionScope())
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(updateSql, conn))
{
  System.Diagnostics.Debug.Assert(
         System.EnterpriseServices.ContextUtil.IsInTransaction);
    
  conn.Open();
    
  int result = cmd.ExecuteNonQuery();

  // We call it success if exactly one record was updated:
  if (result == 1)
  {
    scope.Complete();
  }
}

Here’s the complete class:

// Copyright (c) 2005 Alexander Shirshov
//
// This code is free software; you can redistribute it and/or modify it.
// However, this header must remain intact and unchanged. Additional
// information may be appended after this header. Publications based on
// this code must also include an appropriate reference.
// 
// This code is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE.

using System;
using System.EnterpriseServices;

namespace Omnitalented.EnterpriseServices
{
  public class TransactionScope : IDisposable
  {
    private bool succeded;

    public TransactionScope() : this(TransactionOption.Required, 
                                TransactionIsolationLevel.Any, 60)
    {
    }

    public TransactionScope(TransactionOption transactionOption) : 
           this(transactionOption, TransactionIsolationLevel.Any, 60)
    {
    }

    public TransactionScope(TransactionOption transactionOption, 
           TransactionIsolationLevel isolationLevel, int timeoutSeconds)
    {
      ServiceConfig cfg = new ServiceConfig();
      cfg.Transaction = transactionOption;
      cfg.IsolationLevel = isolationLevel;
      cfg.TransactionTimeout = timeoutSeconds;
            
      ServiceDomain.Enter(cfg);
    }

    public void Complete()
    {
      succeded = true;
    }

    public void Dispose()
    {
      if (succeded)
      {
        ContextUtil.SetComplete();
      } 
      else
      {
        ContextUtil.SetAbort();
      }
      ServiceDomain.Leave();
    }
  }
}

Please note: The code only works in Windows 2003 Server or Windows XP; this is a requirement for the System.EnterpriseServices.ServiceDomain class.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Alexander Shirshov
Web Developer
Russian Federation Russian Federation
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralName using is not declare Pin
BMWABCD23-Jul-08 6:34
memberBMWABCD23-Jul-08 6:34 
GeneralThis vs. .net2.0 TransactionScope + MSDTC Pin
balazs_hideghety26-Mar-07 9:48
memberbalazs_hideghety26-Mar-07 9:48 
QuestionUsage of Transaction Scope Pin
Vijay Kumar Raja Grandhi26-Apr-06 23:27
memberVijay Kumar Raja Grandhi26-Apr-06 23:27 
AnswerRe: Usage of Transaction Scope Pin
Dominik8-Aug-06 4:34
memberDominik8-Aug-06 4:34 
GeneralRe: Usage of Transaction Scope Pin
Dominik8-Aug-06 5:26
memberDominik8-Aug-06 5:26 
GeneralRe: Usage of Transaction Scope Pin
Vijay Kumar Raja Grandhi9-Aug-06 23:53
memberVijay Kumar Raja Grandhi9-Aug-06 23:53 
GeneralRe: Usage of Transaction Scope Pin
kheongchoon25-Sep-06 20:18
memberkheongchoon25-Sep-06 20:18 
GeneralRe: Usage of Transaction Scope Pin
Vijay Kumar Raja Grandhi22-Nov-06 23:22
memberVijay Kumar Raja Grandhi22-Nov-06 23:22 
GeneralRe: Usage of Transaction Scope Pin
balazs_hideghety26-Mar-07 9:51
memberbalazs_hideghety26-Mar-07 9:51 
GeneralBusiness Layer Pin
Anonymous1-Sep-05 20:58
sussAnonymous1-Sep-05 20:58 
GeneralRe: Business Layer Pin
Joey Chömpff1-Sep-05 21:00
memberJoey Chömpff1-Sep-05 21:00 
GeneralRe: Business Layer Pin
balazs_hideghety24-Jun-07 2:09
memberbalazs_hideghety24-Jun-07 2:09 
QuestionTwo connections? two databases? Pin
scubaduba2-Jun-05 22:23
memberscubaduba2-Jun-05 22:23 
AnswerRe: Two connections? two databases? Pin
Alexander Shirshov2-Jun-05 22:56
memberAlexander Shirshov2-Jun-05 22:56 
GeneralRe: Two connections? two databases? Pin
balazs_hideghety26-Mar-07 9:53
memberbalazs_hideghety26-Mar-07 9:53 
GeneralRe: Two connections? two databases? Pin
sanjayjolapra22-Jun-07 22:54
membersanjayjolapra22-Jun-07 22:54 
GeneralRe: Two connections? two databases? Pin
balazs_hideghety24-Jun-07 2:12
memberbalazs_hideghety24-Jun-07 2:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160826.1 | Last Updated 1 Jun 2005
Article Copyright 2005 by Alexander Shirshov
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid