[CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1736755] |
Fri, 01 July 2016 13:46 |
|
Hello Eike,
I have a client with a scenario where two differents users add an element to the same container, one after the other. The container is locked by the first user adding an element until he commits. Then the second user adds his element and commits. This is a classic scenario, but strangely the second user commit is rejected because of a CommitConflictException: Attempt by Transaction[55:3] to modify historical revision. It looks like the invalidation (from the commit of the first user) has not reached the second user. Note that we were monitoring the VM status where the server is located and it was very busy (CPU and RAM).
An easy solution would be to force the second user to wait for this invalidation (not be allowed to modify an historical revision) but I am afraid that it will freeze Eclipse for too long.
Is it possible (and recommended) to force a refresh/invalidation of the cdoObject? I started to try the following way, but I am not sure if it is the right approach and if it is not too dangerous.
Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
for (CDOObject cdoObject : dirtyObjects.values()) {
if(cdoObject.cdoRevision().isHistorical()) {
CDORevision lastRevision = transaction.getRevision(cdoObject.cdoID());
CDORevisionDelta delta = cdoObject.cdoRevision().compare(lastRevision);
CDOStateMachine.INSTANCE.invalidate((InternalCDOObject) cdoObject, delta);
}
}
Regards,
Steve
Steve Monnier - Obeo Canada
Need training or professional services for Sirius?
http://www.obeodesigner.com/sirius
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1736769 is a reply to message #1736755] |
Fri, 01 July 2016 15:29 |
|
Am 01.07.2016 um 15:46 schrieb Steve Monnier:
> Hello Eike,
>
> I have a client with a scenario where two differents users add an element to the same container, one after the other.
> The container is locked by the first user adding an element until he commits. Then the second user adds his element
> and commits. This is a classic scenario, but strangely the second user commit is rejected because of a
> CommitConflictException: Attempt by Transaction[55:3] to modify historical revision.
Did you add a CDOConflictResolver to the transaction of your second user?
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
> It looks like the invalidation (from the commit of the first user) has not reached the second user. Note that we were
> monitoring the VM status where the server is located and it was very busy (CPU and RAM).
> An easy solution would be to force the second user to wait for this invalidation (not be allowed to modify an
> historical revision) but I am afraid that it will freeze Eclipse for too long.
> Is it possible (and recommended) to force a refresh/invalidation of the cdoObject? I started to try the following way,
> but I am not sure if it is the right approach and if it is not too dangerous.
> Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
> for (CDOObject cdoObject : dirtyObjects.values()) {
> if(cdoObject.cdoRevision().isHistorical()) {
> CDORevision lastRevision = transaction.getRevision(cdoObject.cdoID());
> CDORevisionDelta delta = cdoObject.cdoRevision().compare(lastRevision);
> CDOStateMachine.INSTANCE.invalidate((InternalCDOObject) cdoObject, delta);
> }
> }
>
> Regards,
> Steve
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1736905 is a reply to message #1736755] |
Mon, 04 July 2016 10:15 |
|
Am 01.07.2016 um 15:46 schrieb Steve Monnier:
> Hello Eike,
>
> I have a client with a scenario where two differents users add an element to the same container, one after the other.
> The container is locked by the first user adding an element until he commits. Then the second user adds his element
> and commits. This is a classic scenario, but strangely the second user commit is rejected because of a
> CommitConflictException: Attempt by Transaction[55:3] to modify historical revision.
Unless you use explicit locking you must always expect (and handle) commit conflicts. There can always be race
conditions over the wire.
> It looks like the invalidation (from the commit of the first user) has not reached the second user. Note that we were
> monitoring the VM status where the server is located and it was very busy (CPU and RAM).
That could mean that commit notifications are sent and received quite late.
> An easy solution would be to force the second user to wait for this invalidation (not be allowed to modify an
> historical revision) but I am afraid that it will freeze Eclipse for too long.
Not sure how you want to determine what to wait for.
> Is it possible (and recommended) to force a refresh/invalidation of the cdoObject?
No, typically you don't know what to wait for or whether more invalidations would come after.
> I started to try the following way, but I am not sure if it is the right approach and if it is not too dangerous.
> Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
> for (CDOObject cdoObject : dirtyObjects.values()) {
> if(cdoObject.cdoRevision().isHistorical()) {
> CDORevision lastRevision = transaction.getRevision(cdoObject.cdoID());
> CDORevisionDelta delta = cdoObject.cdoRevision().compare(lastRevision);
> CDOStateMachine.INSTANCE.invalidate((InternalCDOObject) cdoObject, delta);
That's definitely very dangerous and not recommended. That's why CDOStateMachine is internal.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1736961 is a reply to message #1736944] |
Mon, 04 July 2016 16:19 |
|
>> Yes we use an explicit locking mechanism, as soon as a element is modified, it is locked.
>It is not possible to create a conflict on a locked object.
Yes, that is why I think the user2 is modifying the element, after the unlock of the element but before the invalidation, both comming from user1 commit.
>> Unfurtunately I cannot attach a test case as the only way to reproduce the issue on my computer was to block the
>> invalidation process.
>What do you mean by "block the invalidation process"?
It is ugly but I avoid the process in CDOViewImpl.doInvalidate if this is concerning the element that is modified by bother user, in order to reproduce the issue on my computer.
In that case, when the second user modifies the element the revision is outdated. transaction.getRevision(cdoObject.cdoID()) returns a newer revision than cdoObject.cdoRevision(). Therefore on modification I am able to check if the element's revision is historical and wait until it is not, hoping it will be received soon.
Steve Monnier - Obeo Canada
Need training or professional services for Sirius?
http://www.obeodesigner.com/sirius
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1737073 is a reply to message #1736961] |
Tue, 05 July 2016 13:46 |
|
As workaround, before user 2 modifies the elements I have added the following instructions:
if(element.cdoRevision().isHistorical()) {
((CDOObjectImpl)element).cdoInternalSetRevision(transaction.getRevision(element.cdoID()));
}
The revision of the element is replaced by the last one. There is no exception on commit because the CDORevisionDelta will be created using the last revision. User2 is only not aware of the element created by User1.
However I am afraid that the fact that isHistorical() and transaction.getRevision(element.cdoID()) return the up-to-date information only because avoiding the CDOViewImpl.doInvalidate process is different that in the real world where the notification is received too late. Is there a way to request directly to the server if a revision is historical and which version is the latest?
Steve Monnier - Obeo Canada
Need training or professional services for Sirius?
http://www.obeodesigner.com/sirius
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1737145 is a reply to message #1736961] |
Wed, 06 July 2016 06:46 |
|
Am 04.07.2016 um 18:19 schrieb Steve Monnier:
>
>>> Yes we use an explicit locking mechanism, as soon as a element is modified, it is locked.
>> It is not possible to create a conflict on a locked object.
> Yes, that is why I think the user2 is modifying the element, after the unlock of the element but before the
> invalidation, both comming from user1 commit.
>
>
>>> Unfurtunately I cannot attach a test case as the only way to reproduce the issue on my computer was to block the
>>> invalidation process.
>> What do you mean by "block the invalidation process"?
> It is ugly but I avoid the process in CDOViewImpl.doInvalidate if this is concerning the element that is modified by
> bother user, in order to reproduce the issue on my computer.
I'm not sure why you're doing that, but it's clearly not recommended. Various problems can result from changing the
internal behaviour. And I can't give support for any such problems.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
>
> In that case, when the second user modifies the element the revision is outdated.
> transaction.getRevision(cdoObject.cdoID()) returns a newer revision than cdoObject.cdoRevision(). Therefore on
> modification I am able to check if the element's revision is historical and wait until it is not, hoping it will be
> received soon.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1737461 is a reply to message #1737145] |
Fri, 08 July 2016 12:38 |
|
As workaround, before user 2 modifies the elements I have added the following instructions:
if(element.cdoRevision().isHistorical()) {
((CDOObjectImpl)element).cdoInternalSetRevision(transaction.getRevision(element.cdoID()));
}
The revision of the element is replaced by the last one. There is no exception on commit because the CDORevisionDelta will be created using the last revision. User2 is only not aware of the element created by User1.
However I am afraid that the fact that isHistorical() and transaction.getRevision(element.cdoID()) return the up-to-date information only because avoiding the CDOViewImpl.doInvalidate process is different that in the real world where the notification is received too late. Is there a way to request directly to the server if a revision is historical and which version is the latest?
Steve Monnier - Obeo Canada
Need training or professional services for Sirius?
http://www.obeodesigner.com/sirius
|
|
|
Re: [CDO] Update an historical revision with modification to an up-to-date and commitable revision [message #1737468 is a reply to message #1737461] |
Fri, 08 July 2016 13:11 |
|
Steve,
Only with an explicit (read or write) lock you can ensure that you atomically get the latest revision of an object and
that nobody else can change the object anymore until you release the lock.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Am 08.07.2016 um 15:38 schrieb Steve Monnier:
> As workaround, before user 2 modifies the elements I have added the following instructions:
> if(element.cdoRevision().isHistorical()) {
> ((CDOObjectImpl)element).cdoInternalSetRevision(transaction.getRevision(element.cdoID()));
> }
> The revision of the element is replaced by the last one. There is no exception on commit because the CDORevisionDelta
> will be created using the last revision. User2 is only not aware of the element created by User1.
>
> However I am afraid that the fact that isHistorical() and transaction.getRevision(element.cdoID()) return the
> up-to-date information only because avoiding the CDOViewImpl.doInvalidate process is different that in the real world
> where the notification is received too late. Is there a way to request directly to the server if a revision is
> historical and which version is the latest?
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Powered by
FUDForum. Page generated in 0.05015 seconds