views:

198

answers:

2

We have an application using the IBM Informix driver. Whenever we try to open connections in parallel, we start getting some really weird errors.

This is the smallest reproduction code I could come up with:

const int Count = 10;
const string ConnectionString = "Host=the_host;Service=the_service;Server=the_server;Database=the_database;User ID=the_user_id;Password=the_password";

static void Main()
{
    var threads = new Thread[Count];
    for (var i = 0; i < threads.Length; i++)
    {
        threads[i] = new Thread(
            number =>
            {
                using (var conn = new IfxConnection(ConnectionString))
                {
                    Console.WriteLine("Opening connection {0}... ", number);
                    try
                    {
                        conn.Open();
                        Console.WriteLine("Opened connection {0}", number);
                        var setLockCommand = conn.CreateCommand();
                        setLockCommand.CommandText = "set lock mode to wait 10;";
                        setLockCommand.ExecuteNonQuery();
                        Console.WriteLine("Releasing connection {0}", number);
                    }
                    catch (IfxException ex)
                    {
                        Console.WriteLine("Failed opening connection {0}: {1}", number, ex);
                    }
                }
            });
        threads[i].Start(i);
    }
    foreach (var thread in threads)
        thread.Join();
}

Depending on which machine we run it on, we had to play a little with the Count value to make it fail, but 10 seems to reproduce the error consistently.

Of course this is not production code, nor how we handle threading, but it highlights the issue without introducting any other variables.

This is the exception stack trace:

IBM.Data.Informix.IfxException: ERROR [HY000] [Informix .NET provider]General error.
   at IBM.Data.Informix.IfxConnection.GetConnectAttr(SQL_ATTR attribute, HANDLER handler)
   at IBM.Data.Informix.IfxConnection.ConnectionIsAlive()
   at IBM.Data.Informix.IfxConnectionPool.BindNodeToConnection(IfxConnPoolNode poolNode, IfxConnection connection, ConnectionPoolType ConnPoolType)
   at IBM.Data.Informix.IfxConnectionPool.Open(IfxConnection connection)
   at IBM.Data.Informix.IfxConnPoolManager.Open(IfxConnection connection)
   at IBM.Data.Informix.IfxConnection.Open()

IBM.Data.Informix.dll version is 3.00.06000.2.

This was tested on Windows 7 (32 and 64 bits) and 2008 (64 bits).

+1  A: 

I asked about this internally, and got the following feedback about the IBM Informix ClientSDK .NET provider:

  1. The issue is not reproducible on our Windows XP 32-bit development machine.
  2. The user/customer is trying to run the application on Windows 7. CSDK 3.00 is NOT certified on Windows 7 (and never will be).
  3. The customer should upgrade to the latest version, CSDK 3.50.TC6 (32-bit) or 3.50.FC6 (64-bit). That is supported. Note that CSDK 3.50.xC5 and earlier fix packs do not support Windows 7.

The Informix.NET provider is also referred to as CSDK .NET provider. It is still the preferred .NET provider used by the majority of IDS customers. The 'latest' IBM Common.NET provider (which works with DB2 as well as IDS using the DRDA protocol, instead of the SQLI protocol used by the CSDK .NET provider) is definitely the future strategy, but few customers are actually using Common.NET for IDS application development.


Since I didn't develop the answer, I've made it Community Wiki.

Jonathan Leffler
Thanks for the research! but I *AM* using CSDK 3.50.TC6 (that's the version number in there, I'm not expecting consistency at this point :-))
Diego Mijelshon
OK - then please take your issue to IBM Technical Support if at all possible.
Jonathan Leffler
A: 

I solved this issue adding a "Pooling=false" on the connection string.

const string ConnectionString = "Host=the_host;Service=the_service;Server=the_server;Database=the_database;User ID=the_user_id;Password=the_password;Pooling=false";
Rafael Mueller
That will *probably* work, but the performance penalty of disabling pooling is probably too big.
Diego Mijelshon