Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Dirty transactions([CDO] Dirty transactions)
[CDO] Dirty transactions [message #1006344] Wed, 30 January 2013 22:29 Go to next message
Andrew Whelan is currently offline Andrew WhelanFriend
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Hello,

I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.

Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.

Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the database (this will be object2, same CDOID and version).

User1 updates object1 and commits.

User2 updates object2 and tries to commit but we get a CommitException because of the old java.util.ConcurrentModificationException.

If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest way to do this for user2? Mind you these users are working in different sessions and user2 might not easily be able to obtain the transaction from object1.

Thanks for your repeated patience. If its any consolation, it looks like we are going to use CDO for this project, long term.

Thanks
-Andrew
PS:

((CDOTransaction)object1.cdoView()).merge(null, 
                               DefaultCDOMerger.PerFeature.ManyValued());

because merging of dirty transactions are not yet supported. It was something to try.
Re: [CDO] Dirty transactions [message #1006368 is a reply to message #1006344] Thu, 31 January 2013 05:31 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 5590
Registered: July 2009
Senior Member
Am 30.01.2013 23:29, schrieb Andrew Whelan:
> Hello,
>
> I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
>
> Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
> Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the
> database (this will be object2, same CDOID and version).
> User1 updates object1 and commits.
>
> User2 updates object2 and tries to commit but we get a CommitException because of the old
> java.util.ConcurrentModificationException.
Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These methods
may also help with conflict detection:

org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()

There's also infrastructure for resolving conflicts automatically:

org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)

In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
explain how it works:

https://bugs.eclipse.org/bugs/attachment.cgi?id=226361


> If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest way
> to do this for user2?
The easiest way is to wrap the modifying and committing code in a try{} block, a rollback() call in the catch{} block
and loop until no exceptions occur during commit() anymore. Note that the correct form also involves synchronizing the
contents of the try{} block on the local transaction to prevent the background invalidation runner from modifying the
model in the middle of related local changes.

> Mind you these users are working in different sessions
That should be of no relevance.

> and user2 might not easily be able to obtain the transaction from object1.
That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
(CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.

> Thanks for your repeated patience. If its any consolation, it looks like we are going to use CDO for this project,
> long term.
Great! It would be awesome if you could take the time to write up a nice review at Ohloh:
https://www.ohloh.net/p/cdo/reviews/new ;-)

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> Thanks
> -Andrew
> PS:
> ((CDOTransaction)object1.cdoView()).merge(null, DefaultCDOMerger.PerFeature.ManyValued());
> because merging of dirty transactions are not yet supported. It was something to try.
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=396804#c2 on why merging is different from conflict resolution.
Re: [CDO] Dirty transactions [message #1034786 is a reply to message #1006368] Fri, 05 April 2013 22:23 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew WhelanFriend
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Eike Stepper wrote on Thu, 31 January 2013 00:31
Am 30.01.2013 23:29, schrieb Andrew Whelan:
> Hello,
>
> I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
>
> Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
> Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the
> database (this will be object2, same CDOID and version).
> User1 updates object1 and commits.
>
> User2 updates object2 and tries to commit but we get a CommitException because of the old
> java.util.ConcurrentModificationException.
Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These methods
may also help with conflict detection:

org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()

There's also infrastructure for resolving conflicts automatically:

org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)

In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
explain how it works:

https://bugs.eclipse.org/bugs/attachment.cgi?id=226361


> If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest way
> to do this for user2?
The easiest way is to wrap the modifying and committing code in a try{} block, a rollback() call in the catch{} block
and loop until no exceptions occur during commit() anymore. Note that the correct form also involves synchronizing the
contents of the try{} block on the local transaction to prevent the background invalidation runner from modifying the
model in the middle of related local changes.

> Mind you these users are working in different sessions
That should be of no relevance.

It doesn't look like I mentioned that the objects are also in different client applications. Two remote clients.
I am using the server configuration with org.eclipse.emf.cdo.server.product.tcp_h2. I have two remote client applications accessing the server.


> and user2 might not easily be able to obtain the transaction from object1.
That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
(CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.
The trouble with this is that object1 and object2 are running in different clients. They are editing the same record and accessing the same server.

I have tried transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
and I created a listener on the transaction, using the example in org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction.

I also tried using an Adaptor like you did in ChangeSubscriptionTest. It works fine if its all is happening in the same client application but I can't seem to get a second client application to recognize that a record has been changed in a different client.

I've tried CDOTransaction.hasConflict(), conflict resolvers don't seem to be any help. Is there anything you can think of that would be different with two separate client applications that are using the same server??

It looks like you are successfully doing this in the Offline example from the webcast. I'm not sure what I could possibly be missing.

I still end up with the ConcurrentModificationException in the second client because I can't detect that it has been changed (or has conflices) until the server throws back the ConcurrentModificationException.

I would even settle with being able to overwrite the one from the first client with the second (it would just be another revision), but the transaction is hosed because the CDOObject represents a historical revision at that point. I tried looping until it let me as you suggested above but it never gets cleared up because its a historical revision.

I'm happy to hear any suggestions that would take me out of this pickle.
Thanks for listing!


> Thanks for your repeated patience. If its any consolation, it looks like we are going to use CDO for this project,
> long term.
Great! It would be awesome if you could take the time to write up a nice review at Ohloh:
https://www.ohloh.net/p/cdo/reviews/new Wink

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> Thanks
> -Andrew
> PS:
> ((CDOTransaction)object1.cdoView()).merge(null, DefaultCDOMerger.PerFeature.ManyValued());
> because merging of dirty transactions are not yet supported. It was something to try.
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=396804#c2 on why merging is different from conflict resolution.

Re: [CDO] Dirty transactions [message #1035015 is a reply to message #1034786] Sat, 06 April 2013 07:13 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 5590
Registered: July 2009
Senior Member
Hi Andrew,

Your reply is a gigantic quote again and I'm unable to parse it ;-(

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Am 06.04.2013 00:23, schrieb Andrew Whelan:
> Eike Stepper wrote on Thu, 31 January 2013 00:31
>> Am 30.01.2013 23:29, schrieb Andrew Whelan:
>> > Hello,
>> >
>> > I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
>> >
>> > Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
>> > Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the >
>> database (this will be object2, same CDOID and version).
>> > User1 updates object1 and commits.
>> >
>> > User2 updates object2 and tries to commit but we get a CommitException because of the old >
>> java.util.ConcurrentModificationException.
>> Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
>> commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These
>> methods may also help with conflict detection:
>>
>> org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
>> org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()
>>
>> There's also infrastructure for resolving conflicts automatically:
>>
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)
>>
>> In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
>> explain how it works:
>>
>> https://bugs.eclipse.org/bugs/attachment.cgi?id=226361
>>
>>
>> > If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest
>> way > to do this for user2? The easiest way is to wrap the modifying and committing code in a try{} block, a
>> rollback() call in the catch{} block and loop until no exceptions occur during commit() anymore. Note that the
>> correct form also involves synchronizing the contents of the try{} block on the local transaction to prevent the
>> background invalidation runner from modifying the model in the middle of related local changes.
>>
>> > Mind you these users are working in different sessions That should be of no relevance.
>>
>> It doesn't look like I mentioned that the objects are also in different client applications. Two remote clients. I am
>> using the server configuration with org.eclipse.emf.cdo.server.product.tcp_h2. I have two remote client applications
>> accessing the server.
>>
>> > and user2 might not easily be able to obtain the transaction from object1.
>> That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
>> (CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.
>> The trouble with this is that object1 and object2 are running in different clients. They are editing the same record
>> and accessing the same server.
>>
>> I have tried transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
>> and I created a listener on the transaction, using the example in
>> org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction.
>>
>> I also tried using an Adaptor like you did in ChangeSubscriptionTest. It works fine if its all is happening in the
>> same client application but I can't seem to get a second client application to recognize that a record has been
>> changed in a different client.
>>
>> I've tried CDOTransaction.hasConflict(), conflict resolvers don't seem to be any help. Is there anything you can
>> think of that would be different with two separate client applications that are using the same server??
>> It looks like you are successfully doing this in the Offline example from the webcast. I'm not sure what I could
>> possibly be missing.
>>
>> I still end up with the ConcurrentModificationException in the second client because I can't detect that it has been
>> changed (or has conflices) until the server throws back the ConcurrentModificationException.
>> I would even settle with being able to overwrite the one from the first client with the second (it would just be
>> another revision), but the transaction is hosed because the CDOObject represents a historical revision at that point.
>> I tried looping until it let me as you suggested above but it never gets cleared up because its a historical revision.
>> I'm happy to hear any suggestions that would take me out of this pickle. Thanks for listing!
>>
>> > Thanks for your repeated patience. If its any consolation, it looks like we are going to use CDO for this project,
>> > long term.
>> Great! It would be awesome if you could take the time to write up a nice review at Ohloh:
>> https://www.ohloh.net/p/cdo/reviews/new ;)
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://www.esc-net.de
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>> >
>> > Thanks
>> > -Andrew
>> > PS:
>> > ((CDOTransaction)object1.cdoView()).merge(null, DefaultCDOMerger.PerFeature.ManyValued());
>> > because merging of dirty transactions are not yet supported. It was something to try.
>> See https://bugs.eclipse.org/bugs/show_bug.cgi?id=396804#c2 on why merging is different from conflict resolution.
>
>
Re: [CDO] Dirty transactions [message #1035240 is a reply to message #1006368] Sat, 06 April 2013 15:08 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew WhelanFriend
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
I'm sorry. When I want to reply I can quote or get this blank box to paste things in. I wish this web application worked like others. When I reply there should automatically be meaningful notation to separate previous replies. I'll remember never to use to quote again. I swear on my project manager's life Smile

Anyhow I hope the following is better. Let me know if it is not.

>> > Hello,
>> >
>> > I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
>> >
>> > Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
>> > Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the database (this will be object2, same CDOID and version).
>> > User1 updates object1 and commits.
>> >
>> > User2 updates object2 and tries to commit but we get a CommitException because of the old java.util.ConcurrentModificationException.
>> Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
>> commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These
>> methods may also help with conflict detection:
>>
>> org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
>> org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()
>>
>> There's also infrastructure for resolving conflicts automatically:
>>
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)
>>
>> In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
>> explain how it works:
>>
>> https://bugs.eclipse.org/bugs/attachment.cgi?id=226361
>>
>>
>> > If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest
>> way > to do this for user2? The easiest way is to wrap the modifying and committing code in a try{} block, a
>> rollback() call in the catch{} block and loop until no exceptions occur during commit() anymore. Note that the
>> correct form also involves synchronizing the contents of the try{} block on the local transaction to prevent the
>> background invalidation runner from modifying the model in the middle of related local changes.
>>
>>
> Mind you these users are working in different sessions
>>That should be of no relevance.


It doesn't look like I mentioned that the objects are also in different client applications. Two remote clients. I am
using the server configuration with org.eclipse.emf.cdo.server.product.tcp_h2. I have two remote client applications
accessing the server.
>>
>> > and user2 might not easily be able to obtain the transaction from object1.
>> That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
>> (CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.
>>

The trouble with this is that object1 and object2 are running in different clients. They are editing the same record
and accessing the same server.

I have tried transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); and I created a listener on the transaction, using the example in org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction.

I also tried using an Adaptor like you did in ChangeSubscriptionTest. It works fine if its all is happening in the
same client application but I can't seem to get a second client application to recognize that a record has been
changed in a different client.

I've tried CDOTransaction.hasConflict(), conflict resolvers don't seem to be any help. Is there anything you can
think of that would be different with two separate client applications that are using the same server??
It looks like you are successfully doing this in the Offline example from the webcast. I'm not sure what I could possibly be missing.

I still end up with the ConcurrentModificationException in the second client because I can't detect that it has been
changed (or has conflices) until the server throws back the ConcurrentModificationException.
I would even settle with being able to overwrite the one from the first client with the second (it would just be
another revision), but the transaction is hosed because the CDOObject represents a historical revision at that point.
I tried looping until it let me as you suggested above but it never gets cleared up because its a historical revision. I'm happy to hear any suggestions that would take me out of this pickle. Thanks for listing!
Re: [CDO] Dirty transactions [message #1035277 is a reply to message #1035240] Sat, 06 April 2013 16:21 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 5590
Registered: July 2009
Senior Member
Am 06.04.2013 17:08, schrieb Andrew Whelan:
> I'm sorry. When I want to reply I can quote or get this blank box to paste things in. I wish this web application
> worked like others. When I reply there should automatically be meaningful notation to separate previous replies. I'll
> remember never to use to quote again. I swear on my project manager's life :)
>
> Anyhow I hope the following is better. Let me know if it is not.
It is ;-)

>
>>> > Hello,
>>> >
>>> > I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
>>> >
>>> > Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
>>> > Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the
>>> database (this will be object2, same CDOID and version).
>>> > User1 updates object1 and commits.
>>> >
>>> > User2 updates object2 and tries to commit but we get a CommitException because of the old
>>> java.util.ConcurrentModificationException.
>>> Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
>>> commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These
>>> methods may also help with conflict detection:
>>>
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()
>>>
>>> There's also infrastructure for resolving conflicts automatically:
>>>
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
>>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)
>>>
>>> In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
>>> explain how it works:
>>>
>>> https://bugs.eclipse.org/bugs/attachment.cgi?id=226361
>>>
>>>
>>> > If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest
>>> way > to do this for user2? The easiest way is to wrap the modifying and committing code in a try{} block, a
>>> rollback() call in the catch{} block and loop until no exceptions occur during commit() anymore. Note that the
>>> correct form also involves synchronizing the contents of the try{} block on the local transaction to prevent the
>>> background invalidation runner from modifying the model in the middle of related local changes.
>>>
>>>
>> Mind you these users are working in different sessions
>>> That should be of no relevance.
>
>
> It doesn't look like I mentioned that the objects are also in different client applications. Two remote clients. I am
> using the server configuration with org.eclipse.emf.cdo.server.product.tcp_h2. I have two remote client applications
> accessing the server.
Ok.

>>>
>>> > and user2 might not easily be able to obtain the transaction from object1.
>>> That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
>>> (CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.
>>>
>
> The trouble with this is that object1 and object2 are running in different clients. They are editing the same record
> and accessing the same server.
You mean user1 and user2? objects normally don't run or edit.

>
> I have tried transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); and I created a listener on the
> transaction, using the example in org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction.
Does any of this involve offline clone repositories? I just noticed that I also have trouble with screen updates in the
Offline Example scenarios. Can you please check whether your client code (adapters, listeners, ...) works in a
not-replicated environment?

>
> I also tried using an Adaptor like you did in ChangeSubscriptionTest. It works fine if its all is happening in the
> same client application but I can't seem to get a second client application to recognize that a record has been
> changed in a different client.
That sounds like a problem in offline replication of change notifications. Please confirm.

>
> I've tried CDOTransaction.hasConflict(), conflict resolvers don't seem to be any help. Is there anything you can think
> of that would be different with two separate client applications that are using the same server??
> It looks like you are successfully doing this in the Offline example from the webcast. I'm not sure what I could
> possibly be missing.
Maybe a regression in M6 or newer I-builds. Please submit a bugzilla.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> I still end up with the ConcurrentModificationException in the second client because I can't detect that it has been
> changed (or has conflices) until the server throws back the ConcurrentModificationException.
> I would even settle with being able to overwrite the one from the first client with the second (it would just be
> another revision), but the transaction is hosed because the CDOObject represents a historical revision at that point.
> I tried looping until it let me as you suggested above but it never gets cleared up because its a historical revision.
> I'm happy to hear any suggestions that would take me out of this pickle. Thanks for listing!
Re: [CDO] Dirty transactions [message #1036481 is a reply to message #1035277] Mon, 08 April 2013 12:42 Go to previous message
Andrew Whelan is currently offline Andrew WhelanFriend
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
> > I'm sorry. When I want to reply I can quote or get this blank box to paste things in. I wish this web application
> > worked like others. When I reply there should automatically be meaningful notation to separate previous replies. I'll
> > remember never to use to quote again. I swear on my project manager's life Smile
> >
> > Anyhow I hope the following is better. Let me know if it is not.
> It is Wink

> >
> > >>> > Hello,
> >>> >
> >>> > I'm having a problem trying to figure out the easiest way to solve the following dirty transaction problem.
> >>> >
> >>> > Lets say we have a CDOObject that a user (user1) has retrieved from the database. We will call this object1.
> >>> > Before any changes are being made to object1 a different user (user2) retrieves the same object/record from the
> >>> database (this will be object2, same CDOID and version).
> >>> > User1 updates object1 and commits.
> >>> >
> >>> > User2 updates object2 and tries to commit but we get a CommitException because of the old
> >>> java.util.ConcurrentModificationException.
> >>> Yes, that's a classical commit conflict. User2 should have been able to fail early, i.e., before even attempting to
> >>> commit, if he had registered a listener with the transaction and reacted to CDOTransactionConflictEvents. These
> >>> methods may also help with conflict detection:
> >>>
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.hasConflict()
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.getConflicts()
> >>>
> >>> There's also infrastructure for resolving conflicts automatically:
> >>>
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.getConflictResolvers()
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.setConflictResolvers(CDOConflictResolver[])
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.addConflictResolver(CDOConflictResolver)
> >>> org.eclipse.emf.cdo.transaction.CDOTransaction.Options.removeConflictResolver(CDOConflictResolver)
> >>>
> >>> In CDO 4.2 I've just fixed a severe bug in CDOMergingConflictResolver and removed its deprecation. These diagrams
> >>> explain how it works:
> >>>
> >>> https://bugs.eclipse.org/bugs/attachment.cgi?id=226361
> >>>
> >>>
> >>> > If I want object2 (user2's object2 data) to overwrite the original commit from user1(object1), what is the easiest
> >>> way > to do this for user2? The easiest way is to wrap the modifying and committing code in a try{} block, a
> >>> rollback() call in the catch{} block and loop until no exceptions occur during commit() anymore. Note that the
> >>> correct form also involves synchronizing the contents of the try{} block on the local transaction to prevent the
> >>> background invalidation runner from modifying the model in the middle of related local changes.
> >>>
> >>>
> >> Mind you these users are working in different sessions
> >>> That should be of no relevance.
> >
> >
> > It doesn't look like I mentioned that the objects are also in different client applications. Two remote clients. I am
> > using the server configuration with org.eclipse.emf.cdo.server.product.tcp_h2. I have two remote client applications
> > accessing the server.
> Ok.

> >>>
> >>> > and user2 might not easily be able to obtain the transaction from object1.
> >>> That should always be possible with (CDOTransaction)(object1.cdoView()) for native models or
> >>> (CDOTransaction)(CDOUtil.getCDOObject(object1).cdoView()) for legacy models.
> >>>
> >
> > The trouble with this is that object1 and object2 are running in different clients. They are editing the same record
> > and accessing the same server.
> You mean user1 and user2? objects normally don't run or edit.

Sorry about the confusing rambling prose. Object1 and Object2 are CDOObjects that point to the same record in the database but are being edited in two different application instances (there are two RCP applications editing the same record).

> >
> > I have tried transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); and I created a listener on the
> > transaction, using the example in org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction.
> Does any of this involve offline clone repositories? I just noticed that I also have trouble with screen > updates in the
> Offline Example scenarios. Can you please check whether your client code (adapters, listeners, ...) works in a
> not-replicated environment?


Actually, no, it doesnt involve offline clone repositories. As I said I am using the org.eclipse.emf.cdo.server.product.tcp_h2 for a server and running two client RCP applications.

The RCP applications communicate with the server using a CDONet4jSession that is set up something like the following:
 IConnector connector = Net4jUtil.getConnector(IPluginContainer.INSTANCE, "tcp", server);
      CDONet4jSessionConfiguration config = CDONet4jUtil.createNet4jSessionConfiguration();
      config.setPassiveUpdateEnabled(true);
      config.setConnector(connector);
      config.setRepositoryName(repository);
      CDONet4jSession session = config.openNet4jSession();


I've tried the PassiveUpdate set to both true and false.

> >
> > I also tried using an Adaptor like you did in ChangeSubscriptionTest. It works fine if its all is happening in the
> > same client application but I can't seem to get a second client application to recognize that a record has been
> > changed in a different client.
> That sounds like a problem in offline replication of change notifications. Please confirm.

No, this isn't offlne. I only mentioned the offline example code org.eclipse.emf.cdo.examples.client.offline.nodes.NodeType.Client.createTransaction as an example of where I saw you setting the change subscription policy like transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); .

Following is what I am doing with it.
 
          sessionTransaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    	 TransactionListener tl = new TransactionListener();
    	 sessionTransaction.addListener(tl);


TransactionListener implements IListener and has an notifyEvent method:
    public void notifyEvent(IEvent event)
    {
      if (event instanceof CDOViewTargetChangedEvent)
      {
    	  System.out.println("transaction changed");
          hasChanged = true;
      }
    }


So again, I have two instances of the application running. This does not fire off when changes are made remotely, (in another application which is pointing to the same database via a CDONet4jSession).

I've tried using an eAdapter scheme, using examples in your org.eclipse.emf.cdo.tests.ChangeSubscriptionTest with no luck. I haven't been able to get CDOTransaction.hasConflict() to detect remote changes either.

BTW: This behavior was the same in M5.

Are there certain settings that the CDOSession and server configuration need for such a thing?

Anyhow I wanted to take another attempt at getting you more information. Do you still want me to create a bugzilla for this?

> >
> > I've tried CDOTransaction.hasConflict(), conflict resolvers don't seem to be any help. Is there anything you can think
> > of that would be different with two separate client applications that are using the same server??
> > It looks like you are successfully doing this in the Offline example from the webcast. I'm not sure what I could
> > possibly be missing.
> Please submit a bugzilla.

> Cheers
> /Eike
Previous Topic:[CDO] Using HSQLDB with CDO 4.2
Next Topic:Create File Browser
Goto Forum:
  


Current Time: Mon Dec 22 00:44:19 GMT 2014

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

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