Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

Ticket #4 (enhancement)

Opened 7 years ago

Last modified 6 years ago

Transaction support

Status: closed (fixed)

Reported by: fumanchu Assigned to: fumanchu
Priority: major Milestone: 1.5
Component: Storage Keywords:
Cc: Estimate (total hours): 8

Change History

10/07/05 11:20:25: Modified by fumanchu

  • milestone set to 1.5.

09/20/06 21:02:51: Modified by fumanchu

  • summary changed from Transactions on flush, flush_all to Transaction support.

Initial work done in [303]. The tests pass, but it should not be considered stable yet. I still need to add some logic to allow users to do their own explicit locking (it's all done implicitly right now), especially since implicit mode requires the user to call sandbox.flush_all rather religiously, usually inside a finally clause.

I also want to add a flag (on the arena?) which allows a developer to specify that their application calls rollback, and therefore requires the deployer to use store(s) which support it.

I'd like to note in passing that almost all of the transaction support is written into geniusql, so it can be re-used without the rest of dejavu.

Finally, note that this changeset re-introduces the restriction that two threads should never share a sandbox; at the least, that's now officially unsupported.

09/21/06 01:59:44: Modified by fumanchu

  • status changed from assigned to closed.
  • resolution set to fixed.

More done in [304]. New geniusql.Database.implicit boolean attribute (default False). Also, rather than put a 'requires_rollback' flag or such on the arena, developers who need rollback are responsible for testing if arena.storage(cls).rollback on their own.

09/21/06 12:40:44: Modified by fumanchu

  • status changed from closed to reopened.
  • resolution deleted.

I'm going to leave this open for now until I get it tested with some apps.

One question: should Database.lock lock out all threads, or just the current one? One problem I'm running into is a main (test suite) thread dropping the database before the previous requests have all committed.

09/23/06 17:51:33: Modified by fumanchu

The last tidbit this really needs is for all sandboxes to register themselves in a weakref map, so they can flush themselves when they go out of scope.

10/03/06 16:23:41: Modified by fumanchu

  • status changed from reopened to closed.
  • resolution set to fixed.

New context manager support in [309]. This allows sandboxes to be their own context managers, so they can auto-flush/rollback when using Python 2.5's 'with' syntax:

from __future__ import with_statement

with arena.new_sandbox() as box:
    box.unit(Thing, ID=3).Name = "DrearyFatBoringOld"

If the above block completes normally, flush_all is called automatically (and commit, too, if db.implicit_trans is True). If an error occurs, rollback is called automatically.

I tried *really* hard to provide the same 'implicit flush' functionality to Python 2.4 and earlier via weakrefs:

class Arena(object):
    def new_sandbox(self):
        """Return a new sandbox object in this Arena."""
        s = Sandbox(self)
        sp = SandboxProxy(s)
        self._sandbox_refs[weakref.ref(sp, self._release_ref)] = s
        return sp

    def _release_ref(self, ref):
        box = self._sandbox_refs.pop(ref)
        box.flush_all()

...but there's no way to guarantee that the weakref callback will be called in the same thread (as the frame that uses 'sp'), since gc collect may be called nondeterministically and do the cleanup/callback. The other issue that I couldn't solve was auto-rollback on error using this scheme (which with/as does nicely).