[Glass] Nested transactions and 'CorruptObj error', or: how to abort in GLASS?
dale.henrichs at gemtalksystems.com
Wed Mar 19 13:47:41 PDT 2014
I've addressed the corruptObj issues in a separate mail, so I'll just
comment below ...
On Wed, Mar 19, 2014 at 4:11 AM, Pieter Nagel <pieter at nagel.co.za> wrote:
> TLDR: how is a GLASS app supposed to handling aborting?
> Our biggest headache porting from GS64 2.4 to 188.8.131.52 relates to aborting.
> Specifically, we have code that does a batch of operations, bulks up all
> error messages, and if there were any errors, wants to abort all side
> effects of the batch and show an error message.
Yes doing an abort "out-of-school" in the seaside stack is not really a
good idea ... commits aren't a real good idea, so it is best to avoid
transactions altogether ...
> Currently, under 2.4, "System rollbackDirtyList: System dirtyListId" is
> used to abort. This was done (apparently on the recommendation of this
> mailing list) as a work-around for the fact that "System abortTransaction"
> breaks horribly - it seems to cause the Seaside machinery and adaptors to
> lose state about the very request that is being handled. But "System
> rollbackDirtyList" no longer exists in 3.1.
It was a bit of a sticky wicket to properly track all of the dirty object
transitions using rollbackDirtyList: and I do think that if you must manage
persistent state in the Seaside stack that nested transactions should be a
better way to go ... when I get out from under 3.2, I'd like to start
looking into some generic support ... if possible ...
> The only "blessed" infrastructure for aborting that seems to be provided
> in GLASS on 2.4 is SafelyPerformBlockRequiringAbort. But the block that
> one can "safely perform" is called outside of the Seaside request handling
> stack, so one can't do any interesting processing like call:'ing a new
> component that shows an error message. Also, it is hard-wired to retry the
> same request again, where in our case that would just lead to re-doing the
> same batch of operations that would just lead to the same errors and the
> same need to abort again.
> GS 3.1 introduces nested transactions, which on the surface would seem to
> be the ideal mechanism to handle these kinds of requirements.
> Ideally, the GLASS infrastructure would enter a nested transaction at a
> suitable boundary before running end-user code, so an application can just
> abort its own subtransaction if it wants to.
Still have to be real careful about the possible transitions between
session state and user state so I'd be inclined to not offer it as a
standard capability ... avoiding all transactions is best ... but in the
use cases where a user is willing to manage things a bit closer, I think it
can find some uses ...
> We first went the route of just wrapping our batch process in a block that
> enters a nested transaction, aborts on exceptions (and re-raises the
> exception, or commits otherwise. But this causes horrible Heisenbugs,
> where at best the current session becomes unusable, and at worst the stone
> file is corrupt.
I'd be interested in getting more details about where you are putting the
transaction boundaries (the ones that "work" and the ones that "don't work"
... the silent unusable are the most interesting ...
> The problems we're having seem similar to the fixed OBJ_ERR_CORRUPT_OBJ
> bugs mentioned in the 184.108.40.206 release notes (even though not explicitly
> saying that they are related to nested transaction), so I'm first going to
> take that for a spin.
Just an FYI, but the corrupt_obj error messages do not always refer to
persistent object corruption .. very often this type of error message is
used when incorrect VM state is detected and the error is intended to
render the session useless so that you aren't able to persist corrupt
> But in the meantime: is our intended use of subtransactions within the
> scope of "sanctioned behaviour" on GLASS?
I'll answer with a "cautious yes" ... the trick is to find the proper
nesting for the transactions ... I can imagine scenarios where seaside is
building up some persistent state and temp state where the temp state is
hooked into the persistent state at a later point in the stack ... an abort
at the wrong spot could easily create a discontinuity between the
persistent state and temp state which would lead to nastiness ... Ideally
the subtransaction would wrap ONLY your user data with no seaside session
state involved at all ... that way an abort will only rollback your data
and leave the session state alone ...
> Glass mailing list
> Glass at lists.gemtalksystems.com
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Glass