Maybe I am missing something....but why not wait until the entire tree
(collections and references) has been materialized before pushing the
object on the cache?

Or, is there a problem with circular references by doing that?

-Andrew



 

-----Original Message-----
From: Armin Waibel [mailto:[EMAIL PROTECTED] 
Sent: Thursday, January 29, 2004 1:31 PM
To: OJB Users List
Subject: Re: [PB API] concurrency problems

Hi Sven,

I can reproduce your problem. It's a really nasty concurrency
materialization problem when using global/shared caches and an object
was materialized first time:

Say we have a class Account with reference to Buyer, Buyer has a
reference to Address and Address has a reference to AddressType (similar
to your test case)

Account -1:1- Buyer -1:1- Address -1:1- AddressType

We set autoretrieve true.

Thread_1: PB lookup Account object. Object was not found in cache, PB
start to materialize Account and push this to cache, then first
reference was materialized and pushed to cache,...

Thread_2: PB lookup Account object. Object was found in cache and
returned. But the found object is the same pushed by thread_1, thus PB
returns a not full materialized Account object.

If a local cache was used, e.g. ObjectCachePerBrokerImpl this situation
will not arise.

Solution is to set attribute 'refresh="true"' in all
reference-descriptor. This force OJB to lookup each reference for an
object whether or not it was found in cache.

regards,
Armin

Sven Efftinge wrote:

> I just changed ObjectCacheClass from DefaultImpl to EmptyImpl.
> Without caching the test doesn't fail.
> I think this happens because the threads don't have to share the 
> objects in this case.
> Sven
> 
> Sven Efftinge wrote:
> 
>> Hi Armin,
>> I wrote a test for this, now.
>> Unfortunately I wrote it against my application, because I haven't 
>> installed the OJB test suite yet ;( The test starts n threads. Each 
>> thread creates a PersistentBroker, retrieves 4 instances of an entity

>> and then checks some references for each entity.
>> When I run the test for 1 thread the test passes.
>> When I run it for e.g. 30 threads the test fails(most of the time) 
>> because some references were null.
>> Mmh... the test fails to RC4, also.
>> I'm not sure if this is really the same problem because I don't get 
>> any errors from OJB directly. Only the null references.
>>
>> Here is the test (I used GroboUtils from SF):
>>
>>    public void testConcurrentRead() throws Throwable {
>>        int numthreads = 30;
>>        TestRunnable[] tests = new TestRunnable[numthreads];
>>
>>        for (int i = 0; i < tests.length; i++) {
>>            tests[i] = new FetchPersistentObjects();
>>        }
>>        MultiThreadedTestRunner testRunner =
>>            new MultiThreadedTestRunner(tests);
>>
>>        testRunner.runTestRunnables();
>>
>>    }
>>
>>    class FetchPersistentObjects extends TestRunnable {
>>              /* (non-Javadoc)
>>         * @see
net.sourceforge.groboutils.junit.v1.TestRunnable#runTest()
>>         */
>>        public void runTest() throws Throwable {
>>            PersistenceBroker broker = null;
>>            KontoIF konto = null;
>>            try {
>>                broker =
>> PersistenceBrokerFactory.createPersistenceBroker(pbKey);
>>                Criteria crit = new Criteria();
>>                crit.addEqualTo(KONTO.NAME, "test");
>>                QueryByCriteria query = new 
>> QueryByCriteria(Konto.class, crit);
>>                //    we have 4 kontos with name="test" in the
database
>>                List kontos = (List)
broker.getCollectionByQuery(query);
>>                for (Iterator iter = kontos.iterator();
iter.hasNext();) {
>>                    konto = (KontoIF) iter.next();
>>                    assertEquals("test", konto.getName());
>>                    assertNotNull("All kontos have a reference to an 
>> interessent", konto.getInteressent());
>>                    assertNotNull("All interessents have a reference 
>> to an adresse", konto.getInteressent().getAdresse());
>>                    assertNotNull("All adresses have a reference to an

>> adresseart", konto.getInteressent().getAdresse().getAdresseart());
>>                    assertNotNull("All adressearts have a varname", 
>> konto.getInteressent().getAdresse().getAdresseart().getVarname());
>>                }
>>            } finally {
>>                broker.close();
>>            }
>>        }
>>
>>    }
>>
>> Armin Waibel wrote:
>>
>>> Hi Sven,
>>>
>>> I don't know if your problem rely on a concurrency problem. Between
>>> rc4 and rc5 I changed handling of DB resources in RsIterator class.
>>> Now OJB is very strict in closing used resources. All resources will

>>> be released when
>>> - PB instance was closed
>>> - PB commit call is done
>>> - PB abort call is done
>>> This helps to avoid abandoned Statement/ResultSet instances.
>>>
>>> > org.apache.ojb.broker.PersistenceBrokerException:
>>> >
org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException:
>>> > Resources no longer reachable, RsIterator will be automatic 
>>> > cleaned up on PB.close/.commitTransaction/.abortTransaction
>>>
>>> The exception says that OJB has already closed the DB resources used

>>> by the Iterator, e.g. one of the three events described above occur.
>>>
>>> Can you post the source code or some pseudo code where the exception

>>> arise?
>>>
>>> regards,
>>> Armin
>>>
>>>
>>> Sven Efftinge wrote:
>>>
>>>> Hi,
>>>> I just got some errors when using/retrieving the same 
>>>> persistentobjects in multiple threads (request cause it's a
webapp).
>>>> I tried many different configurations for class-descriptor, 
>>>> reference-descriptor, ... but the problem was still there.
>>>> At the moment I only have proxy="dynamic" specified all other 
>>>> attributes are set to default.
>>>> I only have the problem with OJB RC5.  RC4 works fine.
>>>>
>>>> This is a sequence from the stacktraces:
>>>>
>>>> Caused by: org.apache.ojb.broker.PersistenceBrokerException: 
>>>> org.apache.ojb.broker.PersistenceBrokerException: 
>>>>
org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: 
>>>> Resources no longer reachable, RsIterator will be automatic cleaned

>>>> up on PB.close/.commitTransaction/.abortTransaction
>>>>   at
>>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.materializeSub
>>>> ject(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.getRealSubject
>>>> (Unknown
>>>> Source)
>>>>   ... 33 more
>>>> Caused by: org.apache.ojb.broker.PersistenceBrokerException: 
>>>>
org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: 
>>>> Resources no longer reachable, RsIterator will be automatic cleaned

>>>> up on PB.close/.commitTransaction/.abortTransaction
>>>>   at
>>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer
>>>> y(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer
>>>> y(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQue
>>>> ry(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.accesslayer.BasePrefetcher.prefetchRelationsh
>>>> ip(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.core.QueryReferenceBroker$PBPrefetchingListen
>>>> er.prefetch(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.core.QueryReferenceBroker$PBMaterializationLi
>>>> stener.beforeMaterialization(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.beforeMaterial
>>>> ization(Unknown
>>>> Source)
>>>>   ... 35 more
>>>> Caused by: 
>>>>
org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: 
>>>> Resources no longer reachable, RsIterator will be automatic cleaned

>>>> up on PB.close/.commitTransaction/.abortTransaction
>>>>   at
>>>> org.apache.ojb.broker.accesslayer.RsIterator.getRsAndStmt(Unknown
>>>> Source)
>>>>   at org.apache.ojb.broker.accesslayer.RsIterator.hasNext(Unknown
>>>> Source)
>>>>   at
>>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer
>>>> y(Unknown
>>>> Source)
>>>>   ... 42 more
>>>>
>>>> Does this has to do with the "prefetch and autoRetreive"-problem 
>>>> discussed on this list in november?
>>>>
>>>> regards,
>>>> Sven
>>>>
>>>> -------------------------------------------------------------------
>>>> -- To unsubscribe, e-mail: [EMAIL PROTECTED]
>>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>> --------------------------------------------------------------------
>>> - To unsubscribe, e-mail: [EMAIL PROTECTED]
>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to