TimeoutException Is Thrown in System.Transactions When Using the IBM Informix OLE DB Provider

Problem Description

A .NET WinForms application creates a distributed transaction that inserts a row into a remote Informix OLE DB database. The .NET app uses System.Transactions and the IBM Informix OLE DB Provider. The transaction starts timing out when calling TransactionScope.Complete().  It is throwing a TransactionAbortedException in one minute. The inner exception is TimeoutException.

If TransactionScope is removed, the code inserts correctly. Using TransactionScope, the record is inserted into the database that can be seen with ISOLATION LEVEL set to DIRTY READ until the transaction aborts.

Cause

You can take a hang dump of the WinForm application process before the exception is thrown using ADPlus or Debug Diagnostic Tool v1.1.

Open the dump in WinDbg.exe and set the symbol path as below:

0:000> .sympath SRV*c:\websymbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: SRV*c:\websymbols*https://msdl.microsoft.com/download/symbols
0:000> .reload

Display the unmanaged callstack::

0:000> kL
ChildEBP RetAddr 
0012ec34 7c90d1fc ntdll!KiFastSystemCallRet
0012ec38 7c8023f1 ntdll!NtDelayExecution+0xc
0012ec90 7c802455 kernel32!SleepEx+0x61
0012eca0 03ef8c74 kernel32!Sleep+0xf
WARNING: Stack unwind information not available. Following frames may be wrong.
00000000 00000000 ifxoledbc!InitDlgProc+0x19974

0:000> lmvm ifxoledbc
start    end        module name
03ed0000 03f20000   ifxoledbc   (export symbols)       ifxoledbc.dll
    Loaded symbol image file: ifxoledbc.dll
    Image path: C:\Program Files\IBM\Informix\Client-SDK\bin\ifxoledbc.dll
    Image name: ifxoledbc.dll
    Timestamp:        Wed Apr 23 07:18:56 2008 (480F1B20)
    CheckSum:         00054EFD
    ImageSize:        00050000
    File version:     3.50.0.13407
    Product version:  3.50.0.13407
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        1.0 App
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      IBM Corporation
    ProductName:      IBM Informix OLE DB Provider
    InternalName:     Ifxoledbc
    OriginalFilename: Ifxoledbc.dll
    ProductVersion:   3.50.TC1
    FileVersion:      3.50.0000
    FileDescription:  IBM Informix OLE DB Provider
    LegalCopyright:   Copyright 2007 IBM Corporation

It is stuck in the IBM Informix OLE DB Provider.

Load the CLR debugger extension sos.dll from the framework directory.

0:000> .load c:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

Display the managed callstack:

0:000> !clrstack
OS Thread Id: 0x12f4 (0)
ESP       EIP    
0012eeb0 7c90e4f4 [ComPlusMethodFrameGeneric: 0012eeb0] System.Data.Common.NativeMethods+ITransactionJoin.JoinTransaction(System.Object, Int32, Int32, IntPtr)
0012eecc 655eff63 System.Data.OleDb.OleDbConnectionInternal.EnlistTransactionInternal(System.Transactions.Transaction, Boolean)
0012ef10 655f008d System.Data.OleDb.OleDbConnectionInternal.Deactivate()
0012ef20 6522dc3a System.Data.ProviderBase.DbConnectionInternal.CloseConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory)
0012ef54 655e99dd System.Data.OleDb.OleDbConnection.Close()
<snip>

OleDbConnectionInternal.Deactivate calls OleDbConnectionInternal.EnlistTransactionInternal that in turn calls ITransactionJoin::JoinTransaction passing a null to it. When null is passed in, System.Data.Common.NativeMethods+ITransactionJoin.JoinTransaction unenlists the transaction (see ITransactionJoin::JoinTransaction). The IBM Informix OLE DB Provider doesn't return from this call until it is timing out.

Resolution

A fix for the bug is available from IBM.