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+0x199740: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.