Tag Archives: Transactions

Lucene.Net and Transactions

Lucene Search Engine Logo

Lucene.Net is an open source full text search engine library (a port from Java). It is stable and works like a charm – I’ve been using Lucene.Net for a couple of years now and implement a handful of solutions. Lucene is awesome.

If you want to try working with Lucene.Net, then the DimeCast.Net crew has recently made two short webcasts introducing Lucene.Net.

.Net 2.0 made it simple to use transactions with the System.Transactions namespace. Two of the great features are automatic elevation to distributed transactions (and utilize the Distributed Transaction Coordinator) and the other is the simplicity of creating your own transactional resource managers.

The .Net Framework defines a resource manager as a resource that can automatically enlist in a transaction managed by System.Transactions – which means that any object that implements any of the following interfaces can enlist in a transaction:

  • IEnlistmentNotification for the two-phase-commit protocol
  • IPromotableSinglePhaseNotification for the single-phase-commit protocol (non-distributed transactions)

To implement a resource manager for the Lucene.Net IndexWriter, and therefore make it transactional, all you have to do is the following:

public class TransactionalIndexWriter : IndexWriter, IEnlistmentNotification
    #region ctor
    public TransactionalIndexWriter(Directory d, Analyzer a, bool create, MaxFieldLength mfl)
        : base(d, a, create, mfl)
    /* More constructors */

    public void EnlistTransaction()
        // Enlist in transaction if ambient transaction exists
        Transaction tx = Transaction.Current;
        if (tx != null)
            tx.EnlistVolatile(this, EnlistmentOptions.None);

    #region IEnlistmentNotification Members
    public void Commit(Enlistment enlistment)

    public void InDoubt(Enlistment enlistment)
        // Do nothing.

    public void Prepare(PreparingEnlistment preparingEnlistment)

    public void Rollback(Enlistment enlistment)

You can use it like so:

IndexWriter indexWriter = null;
TransactionScope tx = null;

    tx = new TransactionScope();
    indexWriter = new TransactionalIndexWriter(...);

    // Perform transactional work
    indexWriter.AddDocument(new Document());
    indexWriter.AddDocument(new Document());
    indexWriter.AddDocument(new Document());

    // Connect to Database, MSMQ etc. to elevate to a distributed transaction

    // Commit transaction
    if (tx != null)

    if (indexWriter != null)

Fairly simply uh? Just remember to instantiate the TransactionalIndexWriter or call the public method EnlistTransaction within the scope of an ambient transaction.
You might consider implementing IDisposable for TransactionalIndexWriter so you can take advantage of the using statement.

I will leave it to the reader to implement a TransactionalIndexReader.

Lucene.Net is an open source full text search engine library (a port from Java). It is stable and works like a charm – I’ve been using Lucene.Net for a couple of years now and implement a handful of solutions. Lucene is awesome.

If you want to try working with Lucene.Net, then the DimeCast.Net crew has recently made two 10 short webcast introducing Lucene.Net (http://dimecasts.net/Casts/ByTag/Lucene).

How to check for and enable read committed snapshot isolation

Run the below query to see which databases that uses read committed snapshot isolation:

SELECT name, is_read_committed_snapshot_on FROM sys.databases

To enable it on a specific database run the below query:

ALTER DATABASE [<databasename>]

As a developer I am in love with read committed snapshot isolation feature for SQL Server 2005+. Transactions can read and write simultaneously the same piece of data – no read/write contention due to row versioning. Writers will block other writers though.

Normal conflicting scenarios:

Simultaneously write and read of the same data.

  • Read committed isolation:  The reader will wait for the writer to release the exclusive lock.
  • Read committed snapshot isolation:  The reader will not block, but receive the latest committed data (latest row version).

Simultaneously writes of the same data.

  • Read committed isolation: The second writer will wait until the first transaction completes because of an exclusive lock.
  • Read committed snapshot isolation: Same as read committed isolation.

Read more about read committed snapshot isolation and isolation levels in the Isolation Levels in SQL Server 2005 article.

Update 02FEB2011: Amended the article due to Tom’s comments.

Great conference

The Miracle SQL Server Open World conference was a great success. There were lots of informative sessions and great networking. I spoke to a lot of interesting people from all over the world including Microsoft SQL Server guys from Redmond and one as far away as from Brisbane, Australia. Bear in mind that this conference is held in the countryside, far away from anything, two hours drive from Copenhagen, Denmark.

I promised the attendances’ at my session “Transactions with Windows Communication Foundation” to post a guide to setup the Distributed Transaction Coordinator (DTC) for WCF. I have posted two guides:

Hope to see all of these interesting people again at next year’s Miracle SQL Server Open World conference.

Configuring the DTC for WCF with WS-AtomicTransaction

If interoperability with other platforms is a requirement WS-Atomic Transaction must be used. It requires all the steps for DTC setup in previous blog entry Configuring the DTC for WCF for OleTx, but also a couple of additional ones.

If running Windows XP or Windows Server 2003 a hotfix is required as detailed in the .Net framework 3.0 release notes. The hotfix can be downloaded from here.

WS-Atomic Transaction requires a certificate to establishing Mutual Trust between the parties in a transaction. If a certificate issued by a trusted 3rd party is not available, it is possible to issue one for test purposes by running the below statement in the Visual Studio 2005 Command Prompt. It generates and installs a certificate in the LocalMachineMY store.

MakeCert -sr LocalMachine -pe -n “CN=mytestcertificate.com” -ss My -sky exchange -sp “Microsoft RSA SChannel Cryptographic Provider” -sy 12

To enable a graphical interface for the WS-AtomicTransaction Configuration Utility (wsatConfig.exe) register the WsatUI.dll by running the following command in the Visual Studio 2005 Command Prompt

regasm /codebase %PROGRAMFILES%Microsoft SDKsWindowsv6.0BinWsatUI.dll

Now open the DTC configuration again by the following steps:

  • Administrative Tools | Component Services | Computer | My Computer.
  • Right-click on My Computer and chose Properties – notice a WS-AT tab is now available
    – select it.
  • Check Enable WS-Atomic Transaction network support
  • Select the certificate under Endpoint certificate

WS-AtomicTrnasaction configuration

Now everything is ready to make use of WS-Atomic Transaction in WCF as long as the client and service are on the same machine.

If the client and service are located on different machines, each machine needs a certificate and any machine participating in a transaction must be explicitly authorized by establishing trust with the counterpart’s certificate.

Establishing trust and authorizing trust. These steps have to be performed on all parties.

  • Export the public key
  • Add the public key certificate to the counterpart’s LocalMachineMY and LocalMachineROOT
  • Authorize the counterpart’s certificate in the WS-AT tab.

It seems like a daunting task, but it is worth it. I can’t figure out how I ever got by with old-style ASMX web services without transactional support.

Configuring the DTC for WCF with OleTx

When a transaction propagates from one process to another, the DTC (Distributed Transaction Manager) must be utilized, because to two or more independent parties are involved in the transaction.

Beforehand the WCF service must be prepared:

  • Decorate the service contract (interface) with the attribute TransactionFlow and specify
    if it is mandatory or allowed.
  • Specify on the service type (implementation) OperationBehavior attribute that a TransactionScope
    is required.
  • Enable transaction propagation on the binding via the transactionFlow element in the
    configuration file for both service and client.

If the service and client are ready and an attempt to propagate a transaction is executed the following TransactionManagerCommunicationException is thrown:

System.Transactions.TransactionManagerCommunicationException was unhandled by user code Message=”Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.”

That is because the DTC does not allow inbound of outbound network transactions, by default.

Configure the client DTC to allow outbound network transactions and the service DTC to have inbound network transactions. If both client and service are running on same machine, enable both inbound and outbound network transactions.

To enable inbound or outbound network transaction navigate to

  • Administrative Tools | Component Services | Computer | My Computer.
  • Right-click on My Computer and chose Properties | MSDTC tab | Security Configuration.
  • Check Network DTC Access and under Transaction Communication Manager check Allow Inbound, Allow Outbound or both.

Now transaction propagation via OLE Transactions (OleTx) is possible. These are all the bindings that operate in a homogeneous Windows environment.