[Glass] Nested transactions and 'CorruptObj error', or: how to abort in GLASS?

Dale Henrichs dale.henrichs at gemtalksystems.com
Tue Mar 25 10:08:50 PDT 2014


Pieter,

I'm glad you have found a satisfactory solution!

Thanks Michael!

Dale


On Tue, Mar 25, 2014 at 7:14 AM, Pieter Nagel <pieter at nagel.co.za> wrote:

> I'm happy to report that our problems with aborting under Seaside in GS3
> are now solved, thanks to advice that I received off-list from Michael
> Veigl.
>
> For the sake of others with this question who may search the archive, I
> reproduce his email below, with his permission:
>
> --- snip ---
>
> Hello Pieter,
>
> We are in the same situation that out of a couple of subsequent actions
> one might
> fail and every change done before must be rolled back to avoid
> inconsistencies.
> Maybe our approach can help you, it is similar to yours but does not use
> native
> nested transactions.
> As you know aborting from within a seaside application is not recommended,
> however
> committing "carefully" should not do harm. Thus we split up execution of
> our domain
> code into two steps. You could as well say, we wrap our code into some
> transaction
> handler.
> So the steps are these:
>
> 1. Do a commit
> We assume that a commit prior to any changes generated by our domain logic
> will not
> lead to inconsistencies within continuations and other seaside specific
> data.
> Such a commit however should be checked for conflicts already at this
> time. Our code
> fragment looks like this:
>         System _validateTransaction <= 0 ifFalse: [WARetryHttpRequest
> signal: 'Transaction
> would not commit, retry'].
>         System commitTransaction.
>         System inTransaction ifFalse: [System beginTransaction]
>
> 2. Perform your domain specific code and check the result
>         a. In case of an error do an abort:
>                 System inTransaction ifTrue: [System abortTransaction].
>                 System beginTransaction
>         The abort is safe because seaside state has been saved before
>         b. If everything goes well just continue, the seaside framework
> will commit later on
>
> It is worth mentioning that you have to guarantee the session being in a
> transaction
> when leaving your domain code, otherwise seaside's own commit would fail.
> In 2.a.
> #beginTransaction could be executed conditionally depending on the session
> being in
> transaction or not.
>
> I hope you get the idea and it works out for you.
>
> Good luck,
> Michael Veigl
>
> --- snip ---
>
> The only thing I changed is, I do not call _validateTransaction before
> commitTransaction. This reads to me like a potential race condition: what
> if between the validate and commit something happens that will make the
> commit fail?
>
> Instead, I call commitTransaction and then do the WARetryHttpRequest in
> case of failure, since commitTransaction will then either commit or fail
> atomically.
>
> _______________________________________________
> Glass mailing list
> Glass at lists.gemtalksystems.com
> http://lists.gemtalksystems.com/mailman/listinfo/glass
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gemtalksystems.com/mailman/private/glass/attachments/20140325/cfb965a0/attachment.html>


More information about the Glass mailing list