I have looked a little more at the code where we have detected the transaction promotion.
It looks like we are using two DataAccessAdapters like this:
public void FirstMethod()
{
using(TransactionScope scope = new TransactionScope())
using (DataAccessAdapter adapter = new DataAccessAdapter(true))
{
// Use adapter to fetch EntityCollection from database.
// Call another class that also accesses the database.
MyObject obj = MyMethod();
scope.Complete();
}
}
// Some method in another object.
public MyObject MyMethod()
{
// In this case, no transaction is started, but of course it will continue to
// use the existing transaction.
using (DataAccessAdapter adapter = new DataAccessAdapter(true))
{
// Fetch EntityCollection from database using this adapter
}
}
I have a stacktrace of where the promption occurs (promotion fails on our test-server):
Message: HandlingInstanceID: e470d4d5-5ac3-4c97-a55b-e64dbacc7333
An exception of type 'System.Transactions.TransactionManagerCommunicationException' occurred and was caught.
------------------------------------------------------------------------------------------------------------
01/24/2007 16:44:17
Type : System.Transactions.TransactionManagerCommunicationException, System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
Source : System.Transactions
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void ProxyException(System.Runtime.InteropServices.COMException)
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.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
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 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.OpenConnection()
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteMultiRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFactory2 entityFactory, IEntityCollection2 collectionToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo, Boolean allowDuplicates, IEntityFields2 fieldsUsedForQuery)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollectionInternal(IEntityCollection2 collectionToFill, IRelationPredicateBucket& filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, Int32 pageNumber, Int32 pageSize)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, IPrefetchPath2 prefetchPath)
at Energinet.DPSApp.Server.Business.Common.TreeStructureManager.ConstructDayTree(DateTime date)
at Energinet.DPSApp.Server.Business.Common.TreeStructureManager.GetDayTree(DateTime date)
at Energinet.DPSApp.Server.Business.Common.TreeStructureManager.GetTimeSeriesType(DateTime date, Int32 id)
at Energinet.DPSApp.Server.Business.Translators.TimeSeriesHeaderTranslator.FillTimeSeriesHeader(TimeSeriesHeader to, TimeSeriesEntity from)
at Energinet.DPSApp.Server.Business.Translators.TimeSeriesHeaderTranslator.ToBusiness(TimeSeriesEntity from)
at Energinet.DPSApp.Server.Business.ActorPlan.TradePlanManager.GetConsumptionPlans(DataAccessAdapter adapter, Actor actor, DateTime date)
at Energinet.DPSApp.Server.Business.ActorPlan.TradePlanManager.GetConsumptionPlans(Actor actor, DateTime date)
at Energinet.DPSApp.Server.ClientServices.ActorPlan.ActorPlanService.GetConsumptionPlans(ActorDTO actorDTO, DateTime date)
In the stacktrace, the method "GetConsumptionPlans" corresponds to "FirstMethod()" - this is the method where the transaction scope is created and the first DataAccessAdapter is created.
The method "ConstructDayTree" corresponds to "MyMethod". This is the method where the second DataAccessAdapter is created.
Is it possible for these two DataAccessAdapters to share the same database connection?
A lot of processing happends inbetween, so it would not be easy for us to pass the a reference to the DataAccessAdapter between the two methods.
Thank you for your help.
Regards
Anders