On Wed, 2005-11-16 at 13:45 -0500, Jonathan LaCour wrote:
> Given that this is also possible, it seems like there are several
> different ways to do this off the top of my head:
>
> 1. WSGI middleware (I think)
> 2. CherryPy filters
> 3. SQLObject modifications
> 4. Decorators
> 5. Some mixture of the above
1. Unfortunately, CherryPy really only has very basic WSGI support - I
don't know of any reasonable way to hook WSGI middleware up to Cherrypy
at this point (maybe in a future release).
2. Filters in CherryPy won't work either, they don't allow you to "wrap"
the request and I don't think there is any way to guarantee that they
are actually run - especially if an exception occurs.
3. SQLObject modifications would be great, but until they are done we'll
need to have an interim solution.
4. Which leaves decorators. My plan now is to implement a transaction
decorator which will look something like:
def in_transaction(func):
hub = AutoConnectHub()
def newfunc(*args, **kw):
hub.begin()
try:
func(*args, **kw)
except cherrypy.HTTPRedirect:
hub.commit()
raise
except:
hub.rollback()
raise
else:
hub.commit()
newfunc.func_name = func.func_name
newfunc.func_doc = func.func_doc
return newfunc
The expose decorator will check the config / it's parameters and if a
transaction is desired it will wrap itself in the in_transaction
decorator.
This doesn't give us strict per-request transactions if you have
database code in your cherrypy filters. But I think any database code
in filters would probably mostly be doing reads, so this doesn't seem to
be a huge issue. It is probably possible to monkeypatch CherryPy to
give us true per-request transactions if we really need them.
The AutoConnectHub.begin method checks to see if we're already in a
transaction, so calling one transaction-wrapped method from another will
result in them both running in one transaction. I think this is the
desired default behavior.
If you need more transaction stuff beyond this, you can always write
your own decorators to do things like nested transactions. And if there
is enough demand we can add support for such things to TG in the future.
Of course, if you want you can disable all of this automatic transaction
stuff in the config and handle transactions yourself or not use
transactions / database at all.
Sean Cazzell