S
S?ren Mondrup
I am using distributed transactions without using COM+. My code works
with OracleClient and our home grown ODBC wrapper, but not with
SqlClient. I get a type cast exception when closing a SqlClient
Connection that participates in a distributed transaction:
Exception: System.Reflection.TargetInvocationException: Exception has
been thrown by the target of an invocation. --->
System.InvalidCastException: Specified cast is not valid.
at System.Data.SqlClient.ConnectionPool.PutConnectionManualEnlisted(SqlInternalConnection
con)
at System.Data.SqlClient.ConnectionPool.PutDeactivatedConnection(SqlInternalConnection
con)
at System.Data.SqlClient.SqlConnection.Close()
My code looks like this:
using( Transaction myTransactionWrapper =
Transaction.Create( "tx unit test", IsolationLevels.ReadCommitted,
TimeSpan.FromSeconds( 20 ) ) )
{
System.EnterpriseServices.ITransaction tx =
myTransactionWrapper.ClrTransaction;
using( SqlConnection con = new SqlConnection() )
{
con.ConnectionString = ConnectionString;
con.Open();
con.EnlistDistributedTransaction( tx );
using( SqlCommand cmd = new SqlCommand() )
{
cmd.Connection = con;
cmd.CommandText = "insert into TxTest values ( 0 )";
cmd.ExecuteNonQuery();
}
con.Close(); // throws exception
}
myTransactionWrapper.Commit();
}
The Transaction class wraps an unmanaged ITransaction.
I obtain the transaction through DtcGetTransactionManagerExProcAddr().
The unmanaged interface pointer is then marshalled to
System.EnterpriseServices.ITransaction with
Marshal.GetTypedObjectForIUnknown(). So I don't use COM+ in any way.
Does anyone know why SqlConnection.Close() throws an exception?
I understand that the connection is supposed to be put into a sub pool
because it participates in a distributed transaction. Could it be that
SqlClient expects a specific implementation of ITransaction, that also
handles this sub pool?
What should I do? Use the "secret" ITransaction implementation? Handle
the sub pool myself? Wait for Whitbey? Wait for Longhorn?
regards Søren Mondrup
with OracleClient and our home grown ODBC wrapper, but not with
SqlClient. I get a type cast exception when closing a SqlClient
Connection that participates in a distributed transaction:
Exception: System.Reflection.TargetInvocationException: Exception has
been thrown by the target of an invocation. --->
System.InvalidCastException: Specified cast is not valid.
at System.Data.SqlClient.ConnectionPool.PutConnectionManualEnlisted(SqlInternalConnection
con)
at System.Data.SqlClient.ConnectionPool.PutDeactivatedConnection(SqlInternalConnection
con)
at System.Data.SqlClient.SqlConnection.Close()
My code looks like this:
using( Transaction myTransactionWrapper =
Transaction.Create( "tx unit test", IsolationLevels.ReadCommitted,
TimeSpan.FromSeconds( 20 ) ) )
{
System.EnterpriseServices.ITransaction tx =
myTransactionWrapper.ClrTransaction;
using( SqlConnection con = new SqlConnection() )
{
con.ConnectionString = ConnectionString;
con.Open();
con.EnlistDistributedTransaction( tx );
using( SqlCommand cmd = new SqlCommand() )
{
cmd.Connection = con;
cmd.CommandText = "insert into TxTest values ( 0 )";
cmd.ExecuteNonQuery();
}
con.Close(); // throws exception
}
myTransactionWrapper.Commit();
}
The Transaction class wraps an unmanaged ITransaction.
I obtain the transaction through DtcGetTransactionManagerExProcAddr().
The unmanaged interface pointer is then marshalled to
System.EnterpriseServices.ITransaction with
Marshal.GetTypedObjectForIUnknown(). So I don't use COM+ in any way.
Does anyone know why SqlConnection.Close() throws an exception?
I understand that the connection is supposed to be put into a sub pool
because it participates in a distributed transaction. Could it be that
SqlClient expects a specific implementation of ITransaction, that also
handles this sub pool?
What should I do? Use the "secret" ITransaction implementation? Handle
the sub pool myself? Wait for Whitbey? Wait for Longhorn?
regards Søren Mondrup