Weird transaction problem with Entity Framework

  • Thread starter Thread starter David Keaveny
  • Start date Start date
D

David Keaveny

I'm experiencing a strange issue with a .NET service I've written that
uses Entity Framework. It creates a new Client entity in my SQL2005
database, then after the exchange of a few messages over an enterprise
service bus, updates the created entity. The initial insert goes fine,
but the update fails with the following error:

2009-04-15 14:26:53,367 ERROR : 'System.Action`1[[System.Object,
mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]' threw an exception consuming
message 'MyProject.Core.Messages.AgencyCreated'
System.Data.EntityException: The underlying provider failed on Open.
---> System.Transactions.TransactionException: The partner transaction
manager has disabled its support for remote/network transactions.
(Exception from HRESULT: 0x8004D025) --->
System.Runtime.InteropServices.COMException (0x8004D025): The partner
transaction manager has disabled its support for remote/network
transactions. (Exception from HRESULT: 0x8004D025)
at System.Transactions.Oletx.IDtcProxyShimFactory.ReceiveTransaction
(UInt32 propgationTokenSize, Byte[] propgationToken, IntPtr
managedIdentifier, Guid& transactionIdentifier,
OletxTransactionIsolationLevel& isolationLevel, ITransactionShim&
transactionShim)
at
System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken
(Byte[] propagationToken)
--- End of inner exception stack trace ---
at System.Transactions.Oletx.OletxTransactionManager.ProxyException
(COMException comException)
at
System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken
(Byte[] propagationToken)
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote
(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState
(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction
tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction
(Transaction transaction)
at System.Transactions.TransactionInterop.GetExportCookie
(Transaction transaction, Byte[] whereabouts)
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie
(Transaction transaction, Byte[] whereAbouts)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull
(Transaction tx)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection
(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.GetConnection
(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection
(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection
(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf
(Boolean openCondition, DbConnection storeConnectionToOpen,
DbConnection originalConnection, String exceptionCode, String
attemptedOperation, Boolean& closeStoreConnectionOnFailure)
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf
(Boolean openCondition, DbConnection storeConnectionToOpen,
DbConnection originalConnection, String exceptionCode, String
attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.Open()
at System.Data.Objects.ObjectContext.EnsureConnection()
at System.Data.Objects.ObjectContext.SaveChanges(Boolean
acceptChangesDuringSave)
at MyProject.Data.Repository.Save(Client client)
at MyProject.Cmas.CreateAccountSaga.Consume(AgencyCreated message)
at
MassTransit.Pipeline.Sinks.MessageTranslator`2.<>c__DisplayClass1.<Enumerate>b__0
(TInput x)
at MassTransit.ServiceBus.DispatchMessageToConsumers
(IResourceLockScope`1 resourceLock, IMessageSelector selector, Object
message)

The Repository.Save method in the stack trace does this:

public void Save(Client client)
{
using (ContractsDataModel model = new ContractsDataModel())
{
EntityClient entityClient;

if (client.Id == 0)
{
entityClient = EntityClient.CreateEntityClient(0, client.Name);
model.AddToEntityClients(entityClient);
}
else
{
entityClient = model.EntityClients.Where(x => x.Id ==
client.Id).First();
}
entityClient.UpdateFrom(client);
model.SaveChanges();
client.Id = entityClient.Id;
}
}

UpdateFrom(client) copies over the various fields from Client to
EntityClient. As I said, the insert part works just fine, but when
updating the created entity, the transaction error occurs. MSDTC seems
to have all the options checked.
 
Never seen the error and I don't use EF like you do - but I might be able to
help. It sounds like the DTC isn't enabled over a remote network, Ive had
similiar problems over VPN.

Go to Control Panel/Administrative Tools/Component Services

Expand Component Services/Computers and right click My Computer, select
Properties, select MSDTC tab then click Security Configuration

Now I don't exactly know what all the options in here do, but you got the
Allow Remote Clients option which is what might be causing the problem so
switch on Allow Remote Clients *on the server* and try again!
--
Best regards...
Mark Baldwin
MB Consultancy | Tel: 07738924224
David Keaveny said:
I'm experiencing a strange issue with a .NET service I've written that
uses Entity Framework. It creates a new Client entity in my SQL2005
database, then after the exchange of a few messages over an enterprise
service bus, updates the created entity. The initial insert goes fine,
but the update fails with the following error:

2009-04-15 14:26:53,367 ERROR : 'System.Action`1[[System.Object,
mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]' threw an exception consuming
message 'MyProject.Core.Messages.AgencyCreated'
System.Data.EntityException: The underlying provider failed on Open.
---> System.Transactions.TransactionException: The partner transaction
manager has disabled its support for remote/network transactions.
(Exception from HRESULT: 0x8004D025) --->
System.Runtime.InteropServices.COMException (0x8004D025): The partner
transaction manager has disabled its support for remote/network
transactions. (Exception from HRESULT: 0x8004D025)
at System.Transactions.Oletx.IDtcProxyShimFactory.ReceiveTransaction
(UInt32 propgationTokenSize, Byte[] propgationToken, IntPtr
managedIdentifier, Guid& transactionIdentifier,
OletxTransactionIsolationLevel& isolationLevel, ITransactionShim&
transactionShim)
at
System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken
(Byte[] propagationToken)
--- End of inner exception stack trace ---
at System.Transactions.Oletx.OletxTransactionManager.ProxyException
(COMException comException)
at
System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken
(Byte[] propagationToken)
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote
(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState
(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction
tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction
(Transaction transaction)
at System.Transactions.TransactionInterop.GetExportCookie
(Transaction transaction, Byte[] whereabouts)
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie
(Transaction transaction, Byte[] whereAbouts)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull
(Transaction tx)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection
(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.GetConnection
(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection
(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection
(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf
(Boolean openCondition, DbConnection storeConnectionToOpen,
DbConnection originalConnection, String exceptionCode, String
attemptedOperation, Boolean& closeStoreConnectionOnFailure)
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf
(Boolean openCondition, DbConnection storeConnectionToOpen,
DbConnection originalConnection, String exceptionCode, String
attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.Open()
at System.Data.Objects.ObjectContext.EnsureConnection()
at System.Data.Objects.ObjectContext.SaveChanges(Boolean
acceptChangesDuringSave)
at MyProject.Data.Repository.Save(Client client)
at MyProject.Cmas.CreateAccountSaga.Consume(AgencyCreated message)
at
MassTransit.Pipeline.Sinks.MessageTranslator`2.<>c__DisplayClass1.<Enumerate>b__0
(TInput x)
at MassTransit.ServiceBus.DispatchMessageToConsumers
(IResourceLockScope`1 resourceLock, IMessageSelector selector, Object
message)

The Repository.Save method in the stack trace does this:

public void Save(Client client)
{
using (ContractsDataModel model = new ContractsDataModel())
{
EntityClient entityClient;

if (client.Id == 0)
{
entityClient = EntityClient.CreateEntityClient(0, client.Name);
model.AddToEntityClients(entityClient);
}
else
{
entityClient = model.EntityClients.Where(x => x.Id ==
client.Id).First();
}
entityClient.UpdateFrom(client);
model.SaveChanges();
client.Id = entityClient.Id;
}
}

UpdateFrom(client) copies over the various fields from Client to
EntityClient. As I said, the insert part works just fine, but when
updating the created entity, the transaction error occurs. MSDTC seems
to have all the options checked.
 
Back
Top