Home » Modeling » EMF » [CDO] Thread race condition with two transactions.
[CDO] Thread race condition with two transactions. [message #431618] |
Sat, 18 July 2009 20:03  |
Eclipse User |
|
|
|
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 #431635 is a reply to message #431634] |
Sun, 19 July 2009 10:27   |
Eclipse User |
|
|
|
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 10:28   |
Eclipse User |
|
|
|
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 10:35   |
Eclipse User |
|
|
|
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 10:37  |
Eclipse User |
|
|
|
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
|
|
|
Goto Forum:
Current Time: Tue Jul 08 22:08:38 EDT 2025
Powered by FUDForum. Page generated in 0.12511 seconds
|