[Seaside] Omnibase transactions and Seaside transactions

Cees de Groot seaside@lists.squeakfoundation.org
Fri, 05 Jul 2002 00:21:59 +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