When querying for a single object through DataObjects.NET Query.Single<T>(id) when using a single thread everything works but if we call Query.Single<T>(id) from multiple threads that are concurrent threads we get the following exception. Each thread is using its own transaction. Is there a solution or work around for this ?

System.InvalidOperationException: The LinkedList node does not belong to
current LinkedList.
at System.Collections.Generic.LinkedList`1.ValidateNode(LinkedListNode`1 node)
at Xtensive.Core.Collections.TopDeque`2.TryGetValue(K key, Boolean moveToTop, V& value)
at Xtensive.Core.Caching.LruCache`2.TryGetItem(TKey key, Boolean markAsHit, T Item& item)
at Xtensive.Storage.Internals.RecordSetReader.Read(IEnumerable`1 source, RecordSetHeader header)
at Xtensive.Storage.Internals.Prefetch.EntityGroupTask.PutLoadedStatesInCache(IEnumerable`1 queryResult, RecordSetReader reader, HashSet`1 foundedKeys)
at Xtensive.Storage.Internals.Prefetch.EntityGroupTask.UpdateCache(HashSet`1 foundKeys)
at Xtensive.Storage.Internals.Prefetch.Fetcher.UpdateCacheFromAllEntityGroupTasks()
at Xtensive.Storage.Internals.Prefetch.Fetcher.ExecuteTasks(IEnumerable`1 containers, Boolean skipPersist)
at Xtensive.Storage.Internals.Prefetch.PrefetchManager.ExecuteTasks(Boolean skipPersist)
at Xtensive.Storage.Providers.SessionHandler.FetchEntityState(Key key)
at Xtensive.Storage.Query.SingleOrDefault(Session session, Key key)
at Xtensive.Storage.Query.Single(Session session, Key key)
at Xtensive.Storage.Query.Single[T](Object[] keyValues)
at Magnetar.Dali.ModDataProvider.Stores.FromModStorageBase`2.GetStorageObjectByID(Guid id) in C:\dev\StarzSvn\CampaignPlanningV1\Source\Common\Magnetar.Dali.ModDataProvider\Stores\ModStorageBase.cs:line 37
at Magnetar.Dali.ModDataProvider.Stores.FromModStorageBase`2.GetBusinessObjectByID(Guid id) in C:\dev\StarzSvn\CampaignPlanningV1\Source\Common\Magnetar.Dali.ModDataProvider\Stores\ModStorageBase.cs:line 42
at Magnetar.Dali.ModDataProvider.ModProjectSearchProvider.<>c__DisplayClass7.<SearchTask>b__2() in C:\dev\StarzSvn\CampaignPlanningV1\Source\Common\Magnetar.Dali.ModDataProvider\ModProjectDataProvider.cs:line 115

asked Oct 27 '11 at 16:32

amorin's gravatar image

amorin
5111

edited Oct 28 '11 at 02:37

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211


5 Answers:

We updated to version 4.4 and this issue no lonher exists. Thanx Steve

answered Nov 14 '11 at 11:44

ssmith's gravatar image

ssmith
20

That's great.

(Nov 15 '11 at 00:30) Dmitri Maximov Dmitri%20Maximov's gravatar image

Hello amorin,

Session and all its internals are not thread-safe. Thereafter, you should perform manual synchronization or use several Session instances to fetch data in parallel.

answered Oct 28 '11 at 03:03

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211

Hum hum hum,

An Entity is bound to its Session so the result the method returns is absolutely unusable in any Session other than the originating one. Moreover, the Entity you return keeps reference to Session instance thus it cannot be collected by GC despite the fact that it is already disposed.

Consider rethinking your architecture, may be usage of Prefetch would help to load data faster. The main idea is to fetch and use entities in the same session and transaction. Crossing boundaries of sessions and transactions will lead to weird errors and unnecessary database roundtrips.

answered Nov 02 '11 at 03:53

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211

Dmitri,

I'm not sure I follow your suggestion. We are currently using a 1 session and 1 transaction per thread and experiencing the exception amorin posted above. Below is a snippet of pseudo code that illustrates what we are doing on each thread. QueryTask is executed on multiple concurrent threads where the input value is different for each and the results collated at a higher level. Is there a specific version of DataObjects.NET we need to be on to use multiple threads, are we doing this wrong, is this a bug, are parallel operations supported in this product?

Tresult QueryTask(Tkey input) {
   using(var session = Session.Open(xxDomainxx))
      using(var transaction = Transaction.Open()) {
         var result = Query.Single<Tresult>(input);
         transaction.Complete();
         return result;
      }
}

answered Oct 31 '11 at 12:03

ssmith's gravatar image

ssmith
20

edited Nov 02 '11 at 03:34

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211

Dmitri,

I understand your point and have verified that we are not using Entity objects outside of their session and transaction scope. The pseudo I posted last time was perhaps over simplified. We are creating business object from the Entity objects within the transaction/session scope and returning those for aggregation by another thread. Is it possible there is a [ThreadStatic] attribute missing somewhere in the Transaction, Session or Entity models?

TBusinessObject QueryTask(Guid key) {
    using(var session = Session.Open(xxDomainxx))
        using(var transaction = Transaction.Open()) {
            var result = Query.Single<TEntity>(key);
            TBusinessObject businessObject = new TBusinessObject();
            businessObject.SimplePropertyA = result.NonEntityPropertyA;
            businessObject.ComplexPropertyB = new ComplexProperty(){ SimplePropertyX = result.EntityPropertyB.X, SimplePropertyY = result.EntityPropertyB.Y };

            transaction.Complete();
            return businessObject;
        }
}

answered Nov 07 '11 at 14:27

ssmith's gravatar image

ssmith
20

edited Nov 08 '11 at 05:53

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211

Hello ssmith,

Thanks for more or less complete sample. Could you specify which version of DataObjects.Net you use and your Session configuration? I think I could try making a test for the scenario or may be you already have one? That would be great.

(Nov 08 '11 at 06:03) Dmitri Maximov Dmitri%20Maximov's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×574

Asked: Oct 27 '11 at 16:32

Seen: 5,074 times

Last updated: Nov 15 '11 at 00:30

powered by OSQA