This mail went unanswered on Microsofts dotnet.framework.adonet newsgroup

SqlConnection throws an exception when disposed if it is manually enlisted
in a distributed transaction. It looks like a bug in the SqlClient
connection pool:

System.InvalidCastException: Specified cast is not valid.
Server stack trace:
  at
System.Data.SqlClient.ConnectionPool.PutConnectionManualEnlisted(SqlInternalConnection
con)
  at
System.Data.SqlClient.ConnectionPool.PutDeactivatedConnection(SqlInternalConnection
con)
  at System.Data.SqlClient.SqlConnection.Close()
  at System.Data.SqlClient.SqlConnection.Dispose(Boolean disposing)
  at System.ComponentModel.Component.Dispose()

The error occurs when the transaction is cast to UCOMIConnectionPoint. I
have tried to enlist in a distributed transaction created by a serviced
component and a transaction created by the DTC proxy. Both yield the same
error. Neither support the IConnectionPoint interface. But they do support
the IConnectionPointContainer interface. I'm not hard core in COM connection
points, but I think the correct way to obtain an IConnectionPoint interface
is to use IConnectionPointContainer. It looks like a bug in
System.Data.SqlClient.ConnectionPool.PutConnectionManualEnlisted.

Below is a simple COM+ example that generates the error.

Has anyone used SqlClient.EnlistDistributedTransaction?
Does anyone know if it is a bug? (It's the same in the the Whitbey beta)
Does anyone have suggestion on how to get around the problem? The only way I
can get it working is to leak the connections :(


Regards Søren Mondrup



-----demo.cs---------------------------------------------- using System; using System.Reflection; using System.Data; using System.Data.SqlClient; using System.EnterpriseServices; using System.Runtime.InteropServices;

[assembly: AssemblyKeyFileAttribute("demo.snk")]

class App
{
 static void Main(string[] args)
 {
   if (args.Length == 0)
   {
     Console.WriteLine("Usage: demo.exe <server_name>");
     return;
   }

   try
   {
     string connStr = "Server=" + args[0] +
       ";Trusted_Connection=SSPI;Database=pubs;Enlist=false;";

     using (ServicedFoo foo = new ServicedFoo())
     {
       foo.DoTransaction(connStr);
     }
   }
   catch(System.Exception e)
   {
     Console.WriteLine(e);
   }
 }
}

[Transaction(TransactionOption.RequiresNew)]
public class ServicedFoo : ServicedComponent
{
 public void DoTransaction(string connStr)
 {
   ITransaction tx = (ITransaction) ContextUtil.Transaction;
   if( tx == null )
     throw new Exception("Failed to create transaction.");

   using (SqlConnection conn = new SqlConnection(connStr))
   {
     conn.Open();
     conn.EnlistDistributedTransaction(tx);
     Console.WriteLine("Enlisted in transaction");
     using (SqlCommand cmd = new SqlCommand("update sales set qty =
qty + 1", conn))
     {
       cmd.ExecuteNonQuery();
     }

     ContextUtil.SetComplete();
     Console.WriteLine("Has voted in favor of commit. Now disposing
connection.");

   } // conn.Dispose() is called and an exception is thrown
 }
}
-----------------------------------------------------------

compile sample with
sn -k demo.snk
csc demo.cs

_________________________________________________________________
Få alle de nye og sjove ikoner med MSN Messenger http://messenger.msn.dk/

===================================
This list is hosted by DevelopMentor®  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 26 Jan 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to