Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Thread race condition with two transactions.
[CDO] Thread race condition with two transactions. [message #431618] Sun, 19 July 2009 00:03 Go to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Hello.

I have the following problem.
I have two threads with each having a CDO transaction of the same session accessing the same
resource. In thread B I imported an object of thread A by using transaction.getObject(). In thread B
I manipulate the object, commit and fire a separate event (with that object attached). That event is
consumed by thread A again which imports the event attached object by it's transaction.getObject().
The problem is now that sometimes the modifications of thread B are visible in thread A, and
sometimes not.
Is there a way to make sure that all updates from the other thread have arrived?

Regards,
Kai
Re: [CDO] Thread race condition with two transactions. [message #431619 is a reply to message #431618] Sun, 19 July 2009 00:35 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Something I should have mentioned. In thread A I use object.cdoReload when that event occurs. I
assumed that by object.cdoReload the repository is checked if there are any updates (and thread B
already committed at that time). But the committed changes are still not there after cdoReload.
So it seems that cdoReload does not do what I expect from it.

Kai Schlamp wrote:
> Hello.
>
> I have the following problem.
> I have two threads with each having a CDO transaction of the same
> session accessing the same resource. In thread B I imported an object of
> thread A by using transaction.getObject(). In thread B I manipulate the
> object, commit and fire a separate event (with that object attached).
> That event is consumed by thread A again which imports the event
> attached object by it's transaction.getObject().
> The problem is now that sometimes the modifications of thread B are
> visible in thread A, and sometimes not.
> Is there a way to make sure that all updates from the other thread have
> arrived?
>
> Regards,
> Kai
Re: [CDO] Thread race condition with two transactions. [message #431620 is a reply to message #431619] Sun, 19 July 2009 01:45 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Forget all those thread things, here is a little test case that demonstrates my problem.
I would have expected that the cdoReload method call would sync the objects between both
transactions, but it doesn't :-(

package org.eclipse.emf.cdo.tests.db;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.transaction.CDOTransaction;

import java.util.ArrayList;
import java.util.List;

public class RaceConditionTest extends AbstractCDOTest
{

public void testLengthAnnotationPositive() throws Exception
{
disableConsole();

msg("Opening session");
CDOSession session = openModel1Session();

msg("Opening transaction");
CDOTransaction transaction1 = session.openTransaction();

msg("Creating resource");
CDOResource resource = transaction1.createResource("/test1");

List<Product1> products = new ArrayList<Product1>();
for (int i = 0; i < 1000; i++)
{
Product1 product = Model1Factory.eINSTANCE.createProduct1();
product.setName("unmodified");
products.add(product);
resource.getContents().add(product);
}
transaction1.commit();

CDOTransaction transaction2 = session.openTransaction();
for (Product1 product : products)
{
Product1 importedProduct = transaction2.getObject(product);
importedProduct.setName("modified");
transaction2.commit();

Product1 reimportedProduct = transaction1.getObject(importedProduct);
((CDOObject)reimportedProduct).cdoReload();
assertEquals("modified", reimportedProduct.getName());
}
}
}
Re: [CDO] Thread race condition with two transactions. [message #431621 is a reply to message #431619] Sun, 19 July 2009 07:17 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Kai,

I fear we must apologize because the reload() methods, i.e.
CDOObject.cdoReload() and CDOView.reload() are meant to be removed:

274111: Remove CDOView.reload
https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111

It seems to be a historical relict and we even could not find out why it
was provided initially (crippeled CVS history after move) ;-(

As an alternative solution in your scenario we could consider adding a
utility method that blocks until a given commit operation of transaction
A is visible in transaction B:

transactionA.commit();
long commitTime = transactionA.getLastCommitTime();
viewB.waitForCommit(commitTime);

Would that help? Please file file an enhancement request ;-)

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper




Kai Schlamp schrieb:
> Something I should have mentioned. In thread A I use object.cdoReload
> when that event occurs. I assumed that by object.cdoReload the
> repository is checked if there are any updates (and thread B already
> committed at that time). But the committed changes are still not there
> after cdoReload.
> So it seems that cdoReload does not do what I expect from it.
>
> Kai Schlamp wrote:
>> Hello.
>>
>> I have the following problem.
>> I have two threads with each having a CDO transaction of the same
>> session accessing the same resource. In thread B I imported an object
>> of thread A by using transaction.getObject(). In thread B I
>> manipulate the object, commit and fire a separate event (with that
>> object attached). That event is consumed by thread A again which
>> imports the event attached object by it's transaction.getObject().
>> The problem is now that sometimes the modifications of thread B are
>> visible in thread A, and sometimes not.
>> Is there a way to make sure that all updates from the other thread
>> have arrived?
>>
>> Regards,
>> Kai


Re: [CDO] Thread race condition with two transactions. [message #431624 is a reply to message #431621] Sun, 19 July 2009 11:28 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
In the meantime I am listening to changes with the help of CDOViewInvalidationEvent and
CDOTransactionHandler, but I still think that this would be a good enhancement.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947

Another question. Is enabling CDOViewInvalidationEvent a big overhead? (I guess that's why it is no
enabled by default).

Eike Stepper wrote:
> Kai,
>
> I fear we must apologize because the reload() methods, i.e.
> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>
> 274111: Remove CDOView.reload
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>
> It seems to be a historical relict and we even could not find out why it
> was provided initially (crippeled CVS history after move) ;-(
>
> As an alternative solution in your scenario we could consider adding a
> utility method that blocks until a given commit operation of transaction
> A is visible in transaction B:
>
> transactionA.commit();
> long commitTime = transactionA.getLastCommitTime();
> viewB.waitForCommit(commitTime);
>
> Would that help? Please file file an enhancement request ;-)
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
>
> Kai Schlamp schrieb:
>> Something I should have mentioned. In thread A I use object.cdoReload
>> when that event occurs. I assumed that by object.cdoReload the
>> repository is checked if there are any updates (and thread B already
>> committed at that time). But the committed changes are still not there
>> after cdoReload.
>> So it seems that cdoReload does not do what I expect from it.
>>
>> Kai Schlamp wrote:
>>> Hello.
>>>
>>> I have the following problem.
>>> I have two threads with each having a CDO transaction of the same
>>> session accessing the same resource. In thread B I imported an object
>>> of thread A by using transaction.getObject(). In thread B I
>>> manipulate the object, commit and fire a separate event (with that
>>> object attached). That event is consumed by thread A again which
>>> imports the event attached object by it's transaction.getObject().
>>> The problem is now that sometimes the modifications of thread B are
>>> visible in thread A, and sometimes not.
>>> Is there a way to make sure that all updates from the other thread
>>> have arrived?
>>>
>>> Regards,
>>> Kai
Re: [CDO] Thread race condition with two transactions. [message #431625 is a reply to message #431624] Sun, 19 July 2009 11:40 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Kai Schlamp schrieb:
> In the meantime I am listening to changes with the help of
> CDOViewInvalidationEvent and CDOTransactionHandler, but I still think
> that this would be a good enhancement.
>
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
Thx.

>
> Another question. Is enabling CDOViewInvalidationEvent a big overhead?
> (I guess that's why it is no enabled by default).
It's not too big, although it can involve some extra threads and EMF
adapter notification.
It's not the default because CDOSessionInvalidationEvent often is a
better alternative, like in this case.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> Eike Stepper wrote:
>> Kai,
>>
>> I fear we must apologize because the reload() methods, i.e.
>> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>>
>> 274111: Remove CDOView.reload
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>>
>> It seems to be a historical relict and we even could not find out why it
>> was provided initially (crippeled CVS history after move) ;-(
>>
>> As an alternative solution in your scenario we could consider adding a
>> utility method that blocks until a given commit operation of transaction
>> A is visible in transaction B:
>>
>> transactionA.commit();
>> long commitTime = transactionA.getLastCommitTime();
>> viewB.waitForCommit(commitTime);
>>
>> Would that help? Please file file an enhancement request ;-)
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>>
>> Kai Schlamp schrieb:
>>> Something I should have mentioned. In thread A I use object.cdoReload
>>> when that event occurs. I assumed that by object.cdoReload the
>>> repository is checked if there are any updates (and thread B already
>>> committed at that time). But the committed changes are still not there
>>> after cdoReload.
>>> So it seems that cdoReload does not do what I expect from it.
>>>
>>> Kai Schlamp wrote:
>>>> Hello.
>>>>
>>>> I have the following problem.
>>>> I have two threads with each having a CDO transaction of the same
>>>> session accessing the same resource. In thread B I imported an object
>>>> of thread A by using transaction.getObject(). In thread B I
>>>> manipulate the object, commit and fire a separate event (with that
>>>> object attached). That event is consumed by thread A again which
>>>> imports the event attached object by it's transaction.getObject().
>>>> The problem is now that sometimes the modifications of thread B are
>>>> visible in thread A, and sometimes not.
>>>> Is there a way to make sure that all updates from the other thread
>>>> have arrived?
>>>>
>>>> Regards,
>>>> Kai


Re: [CDO] Thread race condition with two transactions. [message #431628 is a reply to message #431625] Sun, 19 July 2009 12:03 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
> It's not the default because CDOSessionInvalidationEvent often is a
> better alternative, like in this case.

I just tried it with CDOSessionInvalidationEvent instead, and guess what ... the same problem of not
visible updates in transaction A.
If I listen to CDOSessionInvalidationEvent in thread A, it is not guaranteed that the updates of
transaction B in thread B have already arrived.
With CDOViewInvalidationEvent that works (at least I have not had a problem so far).
Is that really the way it should be?
Re: [CDO] Thread race condition with two transactions. [message #431630 is a reply to message #431628] Sun, 19 July 2009 12:31 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Here is a test snippet that demonstrates the problem with CDOSessionInvalidationEvent. You have to
look at the output. Sometimes it is "modified" and sometimes "unmodified". Strangely the assertion
gets always true, I don't know why!?

package org.eclipse.emf.cdo.tests.db;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.transaction.CDOTransaction;

import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;

import java.util.ArrayList;
import java.util.List;

public class RaceConditionTest extends AbstractCDOTest
{

public void testLengthAnnotationPositive() throws Exception
{
disableConsole();

msg("Opening session");
CDOSession session = openModel1Session();

msg("Opening transaction");
final CDOTransaction transaction1 = session.openTransaction();

msg("Creating resource");
CDOResource resource = transaction1.createResource("/test1");

List<Product1> products = new ArrayList<Product1>();
for (int i = 0; i < 1000; i++)
{
Product1 product = Model1Factory.eINSTANCE.createProduct1();
product.setName("unmodified");
products.add(product);
resource.getContents().add(product);
}
transaction1.commit();

session.addListener(new IListener()
{

public void notifyEvent(IEvent event)
{
if (event instanceof CDOSessionInvalidationEvent)
{
CDOSessionInvalidationEvent invalidationEvent = (CDOSessionInvalidationEvent)event;
for (CDOIDAndVersion cdoIdAndVersion : invalidationEvent.getDirtyOIDs())
{
CDOObject obj = transaction1.getObject(cdoIdAndVersion.getID());
if (obj instanceof Product1)
{
Product1 product = (Product1)obj;
String name = product.getName();
System.out.println(name);
// assertEquals("modified", name); // strange ... why does it not fail?? look at the
output!?
}
}
}
}
});

SecondThread second = new SecondThread(session, products);
Thread thread = new Thread(second);
thread.start();
thread.join();
}

public class SecondThread implements Runnable
{

private CDOTransaction transaction2;

private List<Product1> products;

public SecondThread(CDOSession session, List<Product1> products)
{
transaction2 = session.openTransaction();
this.products = new ArrayList<Product1>();
for (Product1 product : products)
{
this.products.add(transaction2.getObject(product));
}
}

public void run()
{
for (Product1 product : products)
{
product.setName("modified");
transaction2.commit();
}
}
}
}
Re: [CDO] Thread race condition with two transactions. [message #431631 is a reply to message #431630] Sun, 19 July 2009 12:57 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Here also a version where the assertion fails (had to do with the threading):


package org.eclipse.emf.cdo.tests.db;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.transaction.CDOTransaction;

import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;

import java.util.ArrayList;
import java.util.List;

public class RaceConditionTest extends AbstractCDOTest
{
private static boolean allModified = true;

public void testLengthAnnotationPositive() throws Exception
{
disableConsole();

msg("Opening session");
CDOSession session = openModel1Session();

msg("Opening transaction");
final CDOTransaction transaction1 = session.openTransaction();

msg("Creating resource");
CDOResource resource = transaction1.createResource("/test1");

List<Product1> products = new ArrayList<Product1>();
for (int i = 0; i < 1000; i++)
{
Product1 product = Model1Factory.eINSTANCE.createProduct1();
product.setName("unmodified");
products.add(product);
resource.getContents().add(product);
}
transaction1.commit();

session.addListener(new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof CDOSessionInvalidationEvent)
{
CDOSessionInvalidationEvent invalidationEvent = (CDOSessionInvalidationEvent)event;
for (CDOIDAndVersion cdoIdAndVersion : invalidationEvent.getDirtyOIDs())
{
CDOObject obj = transaction1.getObject(cdoIdAndVersion.getID());
if (obj instanceof Product1)
{
Product1 product = (Product1)obj;
String name = product.getName();
System.out.println("- " + name);
if (name.equals("unmodified"))
{
allModified = false;
}
}
}
}
}
});

SecondThread second = new SecondThread(session, products);
Thread thread = new Thread(second);
thread.start();
thread.join();
assertTrue(allModified);
}

public class SecondThread implements Runnable
{

private CDOTransaction transaction2;

private List<Product1> products;

public SecondThread(CDOSession session, List<Product1> products)
{
transaction2 = session.openTransaction();
this.products = new ArrayList<Product1>();
for (Product1 product : products)
{
this.products.add(transaction2.getObject(product));
}
}

public void run()
{
for (Product1 product : products)
{
product.setName("modified");
transaction2.commit();
}
}
}
}
Re: [CDO] Thread race condition with two transactions. [message #431632 is a reply to message #431628] Sun, 19 July 2009 13:43 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Kai Schlamp schrieb:
>> It's not the default because CDOSessionInvalidationEvent often is a
>> better alternative, like in this case.
>
> I just tried it with CDOSessionInvalidationEvent instead, and guess
> what ... the same problem of not visible updates in transaction A.
> If I listen to CDOSessionInvalidationEvent in thread A, it is not
> guaranteed that the updates of transaction B in thread B have already
> arrived.
> With CDOViewInvalidationEvent that works (at least I have not had a
> problem so far).
> Is that really the way it should be?
Sorry, my fault ;-(

Yes, it's meant to be like that: CDOSessionInvalidationEvent indicates
avaiability of new revisions. The same internal code that fires these
events also calls the internal view methods that emit the EMF
notifications and finally fire the CDOViewInvalidationEvent. But the
last two happen asynchronously.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO] Thread race condition with two transactions. [message #431633 is a reply to message #431625] Sun, 19 July 2009 14:16 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
Small comments:

CDOViewInvalidationEvent will always be trigger as soon as you have
objects in your view that are invalidate. You do not control that.

This is different than from the
view.options().isInvalidationNotificationEnabled().
isInvalidationNotificationEnabled will enabled EMF notifications.


Simon



Eike Stepper wrote:
> Kai Schlamp schrieb:
>> In the meantime I am listening to changes with the help of
>> CDOViewInvalidationEvent and CDOTransactionHandler, but I still think
>> that this would be a good enhancement.
>>
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
> Thx.
>
>> Another question. Is enabling CDOViewInvalidationEvent a big overhead?
>> (I guess that's why it is no enabled by default).
> It's not too big, although it can involve some extra threads and EMF
> adapter notification.
> It's not the default because CDOSessionInvalidationEvent often is a
> better alternative, like in this case.
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>> Eike Stepper wrote:
>>> Kai,
>>>
>>> I fear we must apologize because the reload() methods, i.e.
>>> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>>>
>>> 274111: Remove CDOView.reload
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>>>
>>> It seems to be a historical relict and we even could not find out why it
>>> was provided initially (crippeled CVS history after move) ;-(
>>>
>>> As an alternative solution in your scenario we could consider adding a
>>> utility method that blocks until a given commit operation of transaction
>>> A is visible in transaction B:
>>>
>>> transactionA.commit();
>>> long commitTime = transactionA.getLastCommitTime();
>>> viewB.waitForCommit(commitTime);
>>>
>>> Would that help? Please file file an enhancement request ;-)
>>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>>
>>> Kai Schlamp schrieb:
>>>> Something I should have mentioned. In thread A I use object.cdoReload
>>>> when that event occurs. I assumed that by object.cdoReload the
>>>> repository is checked if there are any updates (and thread B already
>>>> committed at that time). But the committed changes are still not there
>>>> after cdoReload.
>>>> So it seems that cdoReload does not do what I expect from it.
>>>>
>>>> Kai Schlamp wrote:
>>>>> Hello.
>>>>>
>>>>> I have the following problem.
>>>>> I have two threads with each having a CDO transaction of the same
>>>>> session accessing the same resource. In thread B I imported an object
>>>>> of thread A by using transaction.getObject(). In thread B I
>>>>> manipulate the object, commit and fire a separate event (with that
>>>>> object attached). That event is consumed by thread A again which
>>>>> imports the event attached object by it's transaction.getObject().
>>>>> The problem is now that sometimes the modifications of thread B are
>>>>> visible in thread A, and sometimes not.
>>>>> Is there a way to make sure that all updates from the other thread
>>>>> have arrived?
>>>>>
>>>>> Regards,
>>>>> Kai
Re: [CDO] Thread race condition with two transactions. [message #431634 is a reply to message #431632] Sun, 19 July 2009 14:19 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Eike Stepper wrote:
> Kai Schlamp schrieb:
>>> It's not the default because CDOSessionInvalidationEvent often is a
>>> better alternative, like in this case.
>> I just tried it with CDOSessionInvalidationEvent instead, and guess
>> what ... the same problem of not visible updates in transaction A.
>> If I listen to CDOSessionInvalidationEvent in thread A, it is not
>> guaranteed that the updates of transaction B in thread B have already
>> arrived.
>> With CDOViewInvalidationEvent that works (at least I have not had a
>> problem so far).
>> Is that really the way it should be?
> Sorry, my fault ;-(
>
> Yes, it's meant to be like that: CDOSessionInvalidationEvent indicates
> avaiability of new revisions. The same internal code that fires these
> events also calls the internal view methods that emit the EMF
> notifications and finally fire the CDOViewInvalidationEvent. But the
> last two happen asynchronously.

Just for clarification ... when I use CDOViewInvalidationEvent in my example I can always assume
that the object in transaction A of thread A is completely updated (with the modifications from
transaction B), and so CDOViewInvalidationEvent is the way to go for me.
Right?

Thanks in advance,
Kai
Re: [CDO] Thread race condition with two transactions. [message #431635 is a reply to message #431634] Sun, 19 July 2009 14:27 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Kai,

Yes, I'll also use CDOViewInvalidationEvent for the new convenience methods.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Kai Schlamp schrieb:
> Eike Stepper wrote:
>> Kai Schlamp schrieb:
>>>> It's not the default because CDOSessionInvalidationEvent often is a
>>>> better alternative, like in this case.
>>> I just tried it with CDOSessionInvalidationEvent instead, and guess
>>> what ... the same problem of not visible updates in transaction A.
>>> If I listen to CDOSessionInvalidationEvent in thread A, it is not
>>> guaranteed that the updates of transaction B in thread B have already
>>> arrived.
>>> With CDOViewInvalidationEvent that works (at least I have not had a
>>> problem so far).
>>> Is that really the way it should be?
>> Sorry, my fault ;-(
>>
>> Yes, it's meant to be like that: CDOSessionInvalidationEvent indicates
>> avaiability of new revisions. The same internal code that fires these
>> events also calls the internal view methods that emit the EMF
>> notifications and finally fire the CDOViewInvalidationEvent. But the
>> last two happen asynchronously.
>
> Just for clarification ... when I use CDOViewInvalidationEvent in my
> example I can always assume that the object in transaction A of thread
> A is completely updated (with the modifications from transaction B),
> and so CDOViewInvalidationEvent is the way to go for me.
> Right?
>
> Thanks in advance,
> Kai


Re: [CDO] Thread race condition with two transactions. [message #431636 is a reply to message #431633] Sun, 19 July 2009 14:28 Go to previous messageGo to next message
Kai Schlamp is currently offline Kai SchlampFriend
Messages: 344
Registered: July 2009
Senior Member
Oh thanks for the hint, Simon. I also must update the FAQ then, as I just added the
CDOViewInvalidationEvent there.

By the way, may I ask you, if you could take a short look in bug 279982
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=279982) some time in the next days.
It would mean much to me and my project.

Simon McDuff wrote:
> Small comments:
>
> CDOViewInvalidationEvent will always be trigger as soon as you have
> objects in your view that are invalidate. You do not control that.
>
> This is different than from the
> view.options().isInvalidationNotificationEnabled().
> isInvalidationNotificationEnabled will enabled EMF notifications.
>
>
> Simon
>
>
>
> Eike Stepper wrote:
>> Kai Schlamp schrieb:
>>> In the meantime I am listening to changes with the help of
>>> CDOViewInvalidationEvent and CDOTransactionHandler, but I still think
>>> that this would be a good enhancement.
>>>
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
>> Thx.
>>
>>> Another question. Is enabling CDOViewInvalidationEvent a big overhead?
>>> (I guess that's why it is no enabled by default).
>> It's not too big, although it can involve some extra threads and EMF
>> adapter notification.
>> It's not the default because CDOSessionInvalidationEvent often is a
>> better alternative, like in this case.
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>> Eike Stepper wrote:
>>>> Kai,
>>>>
>>>> I fear we must apologize because the reload() methods, i.e.
>>>> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>>>>
>>>> 274111: Remove CDOView.reload
>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>>>>
>>>> It seems to be a historical relict and we even could not find out
>>>> why it
>>>> was provided initially (crippeled CVS history after move) ;-(
>>>>
>>>> As an alternative solution in your scenario we could consider adding a
>>>> utility method that blocks until a given commit operation of
>>>> transaction
>>>> A is visible in transaction B:
>>>>
>>>> transactionA.commit();
>>>> long commitTime = transactionA.getLastCommitTime();
>>>> viewB.waitForCommit(commitTime);
>>>>
>>>> Would that help? Please file file an enhancement request ;-)
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>>
>>>> Kai Schlamp schrieb:
>>>>> Something I should have mentioned. In thread A I use object.cdoReload
>>>>> when that event occurs. I assumed that by object.cdoReload the
>>>>> repository is checked if there are any updates (and thread B already
>>>>> committed at that time). But the committed changes are still not there
>>>>> after cdoReload.
>>>>> So it seems that cdoReload does not do what I expect from it.
>>>>>
>>>>> Kai Schlamp wrote:
>>>>>> Hello.
>>>>>>
>>>>>> I have the following problem.
>>>>>> I have two threads with each having a CDO transaction of the same
>>>>>> session accessing the same resource. In thread B I imported an object
>>>>>> of thread A by using transaction.getObject(). In thread B I
>>>>>> manipulate the object, commit and fire a separate event (with that
>>>>>> object attached). That event is consumed by thread A again which
>>>>>> imports the event attached object by it's transaction.getObject().
>>>>>> The problem is now that sometimes the modifications of thread B are
>>>>>> visible in thread A, and sometimes not.
>>>>>> Is there a way to make sure that all updates from the other thread
>>>>>> have arrived?
>>>>>>
>>>>>> Regards,
>>>>>> Kai
Re: [CDO] Thread race condition with two transactions. [message #431637 is a reply to message #431636] Sun, 19 July 2009 14:35 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
The following is working

public void testLengthAnnotationPositive() throws Exception
{
disableConsole();

msg("Opening session");
CDOSession session = openModel1Session();

msg("Opening transaction");
CDOTransaction transaction1 = session.openTransaction();

msg("Creating resource");
CDOResource resource = transaction1.createResource("/test1");

List<Product1> products = new ArrayList<Product1>();
for (int i = 0; i < 1000; i++)
{
Product1 product = Model1Factory.eINSTANCE.createProduct1();
product.setName("unmodified");
products.add(product);
resource.getContents().add(product);
}
transaction1.commit();

final CDOTransaction transaction2 = session.openTransaction();
final ConcurrentValue<Boolean> changed = new
ConcurrentValue<Boolean>(Boolean.FALSE);

transaction1.addListener(new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof CDOViewInvalidationEvent)
{
changed.set(Boolean.TRUE);
}
}
});

for (Product1 product : products)
{
Product1 importedProduct = transaction2.getObject(product);
importedProduct.setName("modified");
transaction2.commit();
changed.acquire(Boolean.TRUE);
changed.set(Boolean.FALSE);

Product1 reimportedProduct = transaction1.getObject(importedProduct);
assertEquals("modified", reimportedProduct.getName());
}
}

Kai Schlamp wrote:
> Oh thanks for the hint, Simon. I also must update the FAQ then, as I
> just added the CDOViewInvalidationEvent there.
>
> By the way, may I ask you, if you could take a short look in bug 279982
> (https://bugs.eclipse.org/bugs/show_bug.cgi?id=279982) some time in the
> next days.
> It would mean much to me and my project.
>
> Simon McDuff wrote:
>> Small comments:
>>
>> CDOViewInvalidationEvent will always be trigger as soon as you have
>> objects in your view that are invalidate. You do not control that.
>>
>> This is different than from the
>> view.options().isInvalidationNotificationEnabled().
>> isInvalidationNotificationEnabled will enabled EMF notifications.
>>
>>
>> Simon
>>
>>
>>
>> Eike Stepper wrote:
>>> Kai Schlamp schrieb:
>>>> In the meantime I am listening to changes with the help of
>>>> CDOViewInvalidationEvent and CDOTransactionHandler, but I still think
>>>> that this would be a good enhancement.
>>>>
>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
>>> Thx.
>>>
>>>> Another question. Is enabling CDOViewInvalidationEvent a big overhead?
>>>> (I guess that's why it is no enabled by default).
>>> It's not too big, although it can involve some extra threads and EMF
>>> adapter notification.
>>> It's not the default because CDOSessionInvalidationEvent often is a
>>> better alternative, like in this case.
>>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>> Eike Stepper wrote:
>>>>> Kai,
>>>>>
>>>>> I fear we must apologize because the reload() methods, i.e.
>>>>> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>>>>>
>>>>> 274111: Remove CDOView.reload
>>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>>>>>
>>>>> It seems to be a historical relict and we even could not find out
>>>>> why it
>>>>> was provided initially (crippeled CVS history after move) ;-(
>>>>>
>>>>> As an alternative solution in your scenario we could consider adding a
>>>>> utility method that blocks until a given commit operation of
>>>>> transaction
>>>>> A is visible in transaction B:
>>>>>
>>>>> transactionA.commit();
>>>>> long commitTime = transactionA.getLastCommitTime();
>>>>> viewB.waitForCommit(commitTime);
>>>>>
>>>>> Would that help? Please file file an enhancement request ;-)
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>> ----
>>>>> http://thegordian.blogspot.com
>>>>> http://twitter.com/eikestepper
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Kai Schlamp schrieb:
>>>>>> Something I should have mentioned. In thread A I use object.cdoReload
>>>>>> when that event occurs. I assumed that by object.cdoReload the
>>>>>> repository is checked if there are any updates (and thread B already
>>>>>> committed at that time). But the committed changes are still not
>>>>>> there
>>>>>> after cdoReload.
>>>>>> So it seems that cdoReload does not do what I expect from it.
>>>>>>
>>>>>> Kai Schlamp wrote:
>>>>>>> Hello.
>>>>>>>
>>>>>>> I have the following problem.
>>>>>>> I have two threads with each having a CDO transaction of the same
>>>>>>> session accessing the same resource. In thread B I imported an
>>>>>>> object
>>>>>>> of thread A by using transaction.getObject(). In thread B I
>>>>>>> manipulate the object, commit and fire a separate event (with that
>>>>>>> object attached). That event is consumed by thread A again which
>>>>>>> imports the event attached object by it's transaction.getObject().
>>>>>>> The problem is now that sometimes the modifications of thread B are
>>>>>>> visible in thread A, and sometimes not.
>>>>>>> Is there a way to make sure that all updates from the other thread
>>>>>>> have arrived?
>>>>>>>
>>>>>>> Regards,
>>>>>>> Kai
Re: [CDO] Thread race condition with two transactions. [message #431638 is a reply to message #431637] Sun, 19 July 2009 14:37 Go to previous message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
The only things that is missing is the following:

CDOViewInvalidationEvent.getView() (TO know from which source is come from).

Simon

Simon McDuff wrote:
> The following is working
>
> public void testLengthAnnotationPositive() throws Exception
> {
> disableConsole();
>
> msg("Opening session");
> CDOSession session = openModel1Session();
>
> msg("Opening transaction");
> CDOTransaction transaction1 = session.openTransaction();
>
> msg("Creating resource");
> CDOResource resource = transaction1.createResource("/test1");
>
> List<Product1> products = new ArrayList<Product1>();
> for (int i = 0; i < 1000; i++)
> {
> Product1 product = Model1Factory.eINSTANCE.createProduct1();
> product.setName("unmodified");
> products.add(product);
> resource.getContents().add(product);
> }
> transaction1.commit();
>
> final CDOTransaction transaction2 = session.openTransaction();
> final ConcurrentValue<Boolean> changed = new
> ConcurrentValue<Boolean>(Boolean.FALSE);
>
> transaction1.addListener(new IListener()
> {
> public void notifyEvent(IEvent event)
> {
> if (event instanceof CDOViewInvalidationEvent)
> {
> changed.set(Boolean.TRUE);
> }
> }
> });
>
> for (Product1 product : products)
> {
> Product1 importedProduct = transaction2.getObject(product);
> importedProduct.setName("modified");
> transaction2.commit();
> changed.acquire(Boolean.TRUE);
> changed.set(Boolean.FALSE);
>
> Product1 reimportedProduct = transaction1.getObject(importedProduct);
> assertEquals("modified", reimportedProduct.getName());
> }
> }
>
> Kai Schlamp wrote:
>> Oh thanks for the hint, Simon. I also must update the FAQ then, as I
>> just added the CDOViewInvalidationEvent there.
>>
>> By the way, may I ask you, if you could take a short look in bug
>> 279982 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=279982) some
>> time in the next days.
>> It would mean much to me and my project.
>>
>> Simon McDuff wrote:
>>> Small comments:
>>>
>>> CDOViewInvalidationEvent will always be trigger as soon as you have
>>> objects in your view that are invalidate. You do not control that.
>>>
>>> This is different than from the
>>> view.options().isInvalidationNotificationEnabled().
>>> isInvalidationNotificationEnabled will enabled EMF notifications.
>>>
>>>
>>> Simon
>>>
>>>
>>>
>>> Eike Stepper wrote:
>>>> Kai Schlamp schrieb:
>>>>> In the meantime I am listening to changes with the help of
>>>>> CDOViewInvalidationEvent and CDOTransactionHandler, but I still think
>>>>> that this would be a good enhancement.
>>>>>
>>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
>>>> Thx.
>>>>
>>>>> Another question. Is enabling CDOViewInvalidationEvent a big overhead?
>>>>> (I guess that's why it is no enabled by default).
>>>> It's not too big, although it can involve some extra threads and EMF
>>>> adapter notification.
>>>> It's not the default because CDOSessionInvalidationEvent often is a
>>>> better alternative, like in this case.
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>> Eike Stepper wrote:
>>>>>> Kai,
>>>>>>
>>>>>> I fear we must apologize because the reload() methods, i.e.
>>>>>> CDOObject.cdoReload() and CDOView.reload() are meant to be removed:
>>>>>>
>>>>>> 274111: Remove CDOView.reload
>>>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=274111
>>>>>>
>>>>>> It seems to be a historical relict and we even could not find out
>>>>>> why it
>>>>>> was provided initially (crippeled CVS history after move) ;-(
>>>>>>
>>>>>> As an alternative solution in your scenario we could consider
>>>>>> adding a
>>>>>> utility method that blocks until a given commit operation of
>>>>>> transaction
>>>>>> A is visible in transaction B:
>>>>>>
>>>>>> transactionA.commit();
>>>>>> long commitTime = transactionA.getLastCommitTime();
>>>>>> viewB.waitForCommit(commitTime);
>>>>>>
>>>>>> Would that help? Please file file an enhancement request ;-)
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>> ----
>>>>>> http://thegordian.blogspot.com
>>>>>> http://twitter.com/eikestepper
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Kai Schlamp schrieb:
>>>>>>> Something I should have mentioned. In thread A I use
>>>>>>> object.cdoReload
>>>>>>> when that event occurs. I assumed that by object.cdoReload the
>>>>>>> repository is checked if there are any updates (and thread B already
>>>>>>> committed at that time). But the committed changes are still not
>>>>>>> there
>>>>>>> after cdoReload.
>>>>>>> So it seems that cdoReload does not do what I expect from it.
>>>>>>>
>>>>>>> Kai Schlamp wrote:
>>>>>>>> Hello.
>>>>>>>>
>>>>>>>> I have the following problem.
>>>>>>>> I have two threads with each having a CDO transaction of the same
>>>>>>>> session accessing the same resource. In thread B I imported an
>>>>>>>> object
>>>>>>>> of thread A by using transaction.getObject(). In thread B I
>>>>>>>> manipulate the object, commit and fire a separate event (with that
>>>>>>>> object attached). That event is consumed by thread A again which
>>>>>>>> imports the event attached object by it's transaction.getObject().
>>>>>>>> The problem is now that sometimes the modifications of thread B are
>>>>>>>> visible in thread A, and sometimes not.
>>>>>>>> Is there a way to make sure that all updates from the other thread
>>>>>>>> have arrived?
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Kai
Previous Topic:first create classes then move them into package
Next Topic:[CDO] CDOID changes when CDOObject is moved - bug or not?
Goto Forum:
  


Current Time: Fri Apr 19 22:59:37 GMT 2024

Powered by FUDForum. Page generated in 0.04073 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top