Re: Dr. Miguel 'Optimistic Locking' Arroz [was Re: WebObjects stress Testing tool?]
Re: Dr. Miguel 'Optimistic Locking' Arroz [was Re: WebObjects stress Testing tool?]
- Subject: Re: Dr. Miguel 'Optimistic Locking' Arroz [was Re: WebObjects stress Testing tool?]
- From: Kieran Kelleher <email@hidden>
- Date: Thu, 3 Dec 2009 10:58:16 -0500
Hi Anjo,
I think this is much different because we are locking the OSC for the
duration of *making* and saving the concurrent changes so that we can
*guarantee* that the snapshot (which is being used by saveChanges for
optimistic locking comparison) has not changed from the time that we
*started* the task. If you are not convinced I can give some examples.
It is explained here: http://terminalapp.net/dr-optimistic-locking/
This extract explains the crunch of the problem:
<cite>
The problem here is the assumption EOF does when saving changes of
attributes with optimistic locking enabled. EOF assumes that the row
snapshots represent the original status of the objects when they were
fetched to the context being saved. So, it compares the current
database status with the original status to detect changes. The
problem is that assumption is simply not true. There can only be one
row snapshot in an EOF stack for a given row, and nothing will
guarantee the snapshot doesn’t change in the middle of the critical
section.
</cite>
And if you use OSC synchronization across and within instances, there
is even a higher risk of that snapshot changing "behind your back"
while making the critical concurrent changes.
In any case, this does work, and I only use it explicitly for those
relatively rare cases where I really need optimistic locking on
something like a workflow state transition task that should only ever
be executed once on a specific EO for example.
Also, in my experience, this technique is rarely used compared to the
more common scenario of saveTolerantly, refresh, merge changes,
etc. ... and many apps may never have business logic that requires
this technique. I have one app (
Regards, Kieran
On Dec 3, 2009, at 10:09 AM, Anjo Krank wrote:
Do you need to do anything different from ERXEC.saveTolarantly(b,b,b)?
Cheers, Anjo
Am 03.12.2009 um 16:02 schrieb Kieran Kelleher:
By the way Miguel, I made a little Optimistic lock action utility
class to handle this (similar to how
ERXEOAccessUtilities.ChannelAction is constructed)... you might
find it useful....... example of usage nippet is shown after the
class listing below .......
<snip content = "snippet of static inner class from my EO utilities
class">
/**
*Dealswiththenitty-grittyofacritical<strong>short-running</strong>
*taskwherewedependonoptimisticlockingtoguaranteethatanother
*processdoesnotchangeoptimisticlockingattributesatthesametime.To
*understandwhythisisnecessary,readthis:
*{@link http://terminalapp.net/dr-optimistic-locking/}.
*
*Wrapstheactionsin
*appropriatelocks.WARNING:TheOSCislockedfortheperiodofthe
*transaction.AllEOFaccessonthisOSCisblocked.Donotusethisfor
*actionsthattakemorethanafewmillisecondsonOSC'sthatarebeing
*usedbyrequestthreads!
*
*Codedesigninspiredby{@link ERXEOAccessUtilities.ChannelAction}
*
*@authorkieran
*/
public static abstract class OptimisticLockAction {
/**
*Thismethodiscalledinanewlockededitingcontextthathasbeen
*createdintheoscpassedin.Performyourchangesinthisediting
*context.Anyerrorswillbethrown.Returnanyresultyouwant.
*
*@paramosc
*/
protected abstract Object doPerform(EOEditingContext ec);
public Object perform() throws Exception {
return perform(null);
}
/**
*@paramosc
* therootobjectstoretobelockedsothattrueoptimistic
* lockingcanbeenforced.
*@returntheresultofyourdoPerformmethodimplementation
*@throwsException
*/
public Object perform(EOObjectStore osc) throws Exception {
osc.lock();
try {
ERXEC ec = (ERXEC) ERXEC.newEditingContext(osc);
ec.setCoalesceAutoLocks(false);
ec.setUseAutoLock(false);
ec.lock();
try {
// Don't use stale EO's to begin with
ec.setFetchTimestamp(System.currentTimeMillis());
return doPerform(ec);
} catch (Exception e) {
throw e;
} finally {
ec.unlock();
ec.dispose();
}
} catch (Exception e) {
throw e;
} finally {
osc.unlock();
}
}
}
</snip>
<snip content = "example usage">
// Create a new Optimistic Lock action
OptimisticLockAction action = new WKEOUtils.OptimisticLockAction() {
@Override
protected Object doPerform(EOEditingContext actionEditingContext)
{
CTCampaign localCampaign = (CTCampaign)
actionEditingContext.faultForGlobalID(gid, actionEditingContext);
try {
// Make the critical concurrent changes that depend on
optimistic locking failure
localCampaign.shipMessages();
actionEditingContext.saveChanges();
} catch (EOGeneralAdaptorException e) {
// Handle the optimistic lock failure ...
}
return null;
}
};
// Perform the optimistic lock action
try {
action.perform(parentObjectStore());
} catch (Exception e) {
// Unexpected exception
throw new NestableRuntimeException(e);
}
</snip>
On Dec 3, 2009, at 8:45 AM, Miguel Arroz wrote:
Hello
We use JMeter, not so much to test how much load can the server
get, but to test my beloved weird concurrency handling situations.
As almost any software in the world, it sucks specially at the UI
level (it's far from being integrated in OS X, not even copy/paste
works between it and the Mac world), and you have to allocate it a
lot of RAM or it will eventually blow up the heap, but it gets the
job done.
Yours
Miguel Arroz
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
@krank.net
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden