[Seaside] Omnibase transactions and Seaside transactions

Cees de Groot seaside@lists.squeakfoundation.org
Fri, 05 Jul 2002 00:27:00 +0200


I'm trying to get my head around combining OmniBase transactions and
Seaside transactions, with not much luck sofar.

The issue is that persistent objects in OmniBase only are valid in the
context of a transaction. When you mark them dirty, OmniBase looks for
the OID of the object which it only finds when the object was read from
the database in the current transaction ('current' as in 'found in the
process->transaction dictionary'). So if you accidentally read an object
in Txn A and then modify it in Txn B, you get an error.

A case study: a list of news items (for a sort of weblog page). There
are two pages - the list of items, and an edit page for a single item.

I'm using a subclass of IASession that sets up an OmniBase transaction
in aboutToView, so that the current process always has a transaction
(IIRC, every web hit of a session is done in the same process, not?). So
the list of items is read and rendered inside the default transaction.
Now, I want to edit a single item so I click on the edit link of one of
the items.

edit: anItem
    session isolate: [NewsItemEditor new item: anItem]

is the basic idea. My IASession subclass does a transaction for the
isolate as well. In the actual code, there is some wrapping going on:
because 'anItem' will not be valid inside the new transaction that is
active inside the #isolate:, I wrap its OID inside a proxy; when the
object is accessed in the new transaction, its DNU handler grabs the
real object through the OID (so the object is now read and therefore
valid within the new transaction) and forwards all messages to it.
Somehow, the object is historically called a 'ReusableReference'
(reference to an object reusable accross transactions):

edit: anItem
    | ref |
    ref := ReusableReference for: anItem
    session isolate: [NewsItemEditor new item: ref]

It all works reasonably well, but it is a long shot from all the
transparency that Seaside offers. And it gets worse: if you edit a news
item, and you press 'Save', you return from the #isolate: block back in
the same transaction - of course, OmniBase has all the objects cached so
when you return from the edit to the news item list, you don't see any
of your changes.

Solution: close the OmniBase transaction and fire up a new one at the
end of the #isolate: - to that end, I have overridden #closeTransaction
to rollback and nillify the OmniBase transaction; the next #aboutToView
will then start a new transaction and the changes show up.

Nice, but now you have: (show list in txn A) (edit item in txn B) (show
list in txn C), and guess what happens if you press back twice (going
back to the first list, in txn A) and then press a button - OmniBase
will barf because txn A was closed so the seaside transaction context is
in fact invalid.

Short summary: it's a bit of a mess :-). Any hints on whether this is
resolvable are more then welcome...

Regards,

Cees