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: Miguel Arroz <email@hidden>
- Date: Thu, 3 Dec 2009 15:26:32 +0000
Hi!
I think so. This concurrency stuff is confusing, but it looks like
saveChangesTolerantly relies on EOF Optimistic Locking. The problem is
that EOF's Optimistic Locking is useless unless the OSC is locked, due
to the reasons I have on that blog post, and that were already
discussed here a few times. There's a disagreement between me and
other people about this, I think OL is just broken, other people say
it's a feature, not a bug :), but the point is, unless you lock OSC,
some situations that should trigger an OL simply won't.
The saveChangesTolerantly is useful to avoid writing a few lines of
code (the read-again, change-again, try-to-write-again cycle) in some
cases (like when you're changing a simple property in one object).
However, we have very complex logic with data that depends on other
data, so if we hit an OL exception, it would be so confusing to
recover from that error that we prefer to throw everything away and
start again from scratch.
I still believe snapshots should be linked to an EC and not an OSC
to avoid this problem, although that would require some heavy changing
to EOF.
Yours
Miguel Arroz
On 2009/12/03, at 15:09, 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
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
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