Thread: [SQLObject] caching, threading & zope
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <gs...@sy...> - 2003-10-04 20:09:23
Attachments:
oodb.py
|
hello, i just played a little bit around with sqlobject and have a few questions: 1) according to the documentation "_cacheValue = False" should be used when using transactions. what is the reason for this (especially when using serialized transactions i can't see any cause for problems when using caching)? 2) are sqlobject calls (e.g. connection.transaction()) threadsafe or do i need to take care of this? 3) btw, i created a small proxy class to bind sqlobject transactions to zope transactions (it's attached to this mail if anyone is interested). to use this class it's required to run zope under python2.2 (that's already the default in debian/unstable). usage example: def frob(self, REQUEST): 'testmethod' trans = oodb.new_transaction() person = oodb.Person6.select(connection = trans) (manually passing the transaction to each method is a little bit ugly, but i haven't figured out yet how to do this automatically.) cu /gst <oodb.py> |
From: Ian B. <ia...@co...> - 2003-10-04 20:39:40
|
On Sat, 2003-10-04 at 15:08, Günther Starnberger wrote: > hello, > > i just played a little bit around with sqlobject and have a few questions: > > 1) according to the documentation "_cacheValue = False" should be used when > using transactions. what is the reason for this (especially when using > serialized transactions i can't see any cause for problems when using > caching)? That's not really true anymore for CVS -- transactions aren't really working properly in 0.4. CVS has an expire method on SQLObject instances, which is called when an object is rolled back -- since 0.4 didn't have this you couldn't use the attribute caching with transactions (since it wouldn't be accurate after a rollback). However, while rollback expires objects in the transaction, commit doesn't expire objects outside of the transaction. But I'm not really sure how that should work anyway. > 2) are sqlobject calls (e.g. connection.transaction()) threadsafe or do i > need to take care of this? Yes, these should be threadsafe, though it depends on the exact context of course -- SQLObject can't address all concurrency issues. That call in particular should be threadsafe. For the most part all SQLObject calls should be threadsafe, but that doesn't mean your instances will be threadsafe, depending on how you use them. I haven't really made use of the DB-API threadsafety variable. Though generally SQLObject is assuming a lowest-common-denominator, where threads cannot concurrently use the same connection (threadsafety level 1). There is one specified lower level (the whole module is not threadsafe), but I don't think any supported databases have that problem. > 3) btw, i created a small proxy class to bind sqlobject transactions to zope > transactions (it's attached to this mail if anyone is interested). to use > this class it's required to run zope under python2.2 (that's already the > default in debian/unstable). > > usage example: > def frob(self, REQUEST): > 'testmethod' > trans = oodb.new_transaction() > person = oodb.Person6.select(connection = trans) > > (manually passing the transaction to each method is a little bit ugly, but i > haven't figured out yet how to do this automatically.) Seems like you could go further, and just do: Transaction._abort = Transaction.rollback Transaction._finish = Transaction.commit Transaction._begin = lambda self: None Then (if I read your proxy correctly) the transaction can be used directly. Though really that should be done in a subclass of Transaction, and then mess with the .transaction() method to use a different class. As for passing the transaction, yes, it's a little annoying. I don't know how Zope does this for Z SQL Methods, but the problem is pretty much the same. Does Zope use Acquisition for this, or maybe using one transaction per thread? Modeling has a notion of an "editing context" which can make sense. Really that's just a different phrasing of the same concept -- but instead of passing the connection to your class, your class gets passed to the connection. Ian |
From: <gs...@sy...> - 2003-10-04 22:25:34
Attachments:
oodb.py
|
On 2003-10-04 22:40:30 +0200 Ian Bicking <ia...@co...> wrote: hello, > That's not really true anymore for CVS -- transactions aren't really > working properly in 0.4. CVS has an expire method on SQLObject > instances, which is called when an object is rolled back -- since 0.4 > didn't have this you couldn't use the attribute caching with > transactions (since it wouldn't be accurate after a rollback). ok :) - i am currently using the CVS version because i only got a traceback when using transactions under 0.4. btw, there's a typo in the 'transaction' chapter of the documentation ('_cacheValue' instead of '_cacheValues'). > However, while rollback expires objects in the transaction, commit > doesn't expire objects outside of the transaction. But I'm not really > sure how that should work anyway. are there any reasons to mix queries which use transactions with queries which doesn't in an application? > Seems like you could go further, and just do: > > Transaction._abort = Transaction.rollback > Transaction._finish = Transaction.commit > Transaction._begin = lambda self: None > > Then (if I read your proxy correctly) the transaction can be used > directly. Though really that should be done in a subclass of > Transaction, and then mess with the .transaction() method to use a > different class. subclassing from both Transaction and TM isn't that easy/clean because method names are overlapping (e.g. commit()). just adding the methods to the class doesn't work either, because the transaction has to register itself via the _register method first (which calls TM's commit() method). (i have attached a new shorter version of the transaction proxy which i am currently using.) > As for passing the transaction, yes, it's a little annoying. I don't > know how Zope does this for Z SQL Methods, but the problem is pretty > much the same. Does Zope use Acquisition for this, or maybe using one > transaction per thread? i guess it's using acquisition, but i haven't looked into the source yet. cu /gst <oodb.py> |