> For the potentially many methods that are just reading data, you don't
> really want a transaction, and decorators are a nice way to configure
> where you want the transaction.
I fail to see the harm in starting a transaction for read-only
methods? What's the big deal? It seems like transactional integrity
is pretty important, and automating it would be really nice :)
Assuming that most methods are "read only" is assuming things about
the application. That isn't safe to do, because there are many types
of applications. Some will be largely reading, others may be largely
update/create/delete, others may be an even split. You don't know
which is the primary case. What you *do* know is that read-only
methods can safely run in a transaction and that other methods *have
to* run in a transaction. If you run in a transaction in both cases,
everything is good. If you don't, then something can go wrong.
Seems like we have found our default, no?
In addition, maybe methods are read-only, but something behind the
scenes is doing some database work, possibly in a filter, like
logging certain views to the database, or updating a "last_access"
field in a session database backend. In these scenarios, you might
want a transaction. Its just too hard to tell.
Seems like "transaction-per-request always" is the absolute safest
bet, at least to me, and I don't see the harm in making it the
default. Of course, I am only going on my experience, and I am sure
that there are people who will disagree with me there.
> Now that i think about it,
> transactions are already maintained on the thread level so it should
> be fairly straightforward to keep reusing the same transaction. As
> Roman points out, there may be times where you want to use nested
> transactions (just make sure you're not using sqlite). So the trick is
> finding the best defaults and an easy way to diverge from the default.
Fair enough, but you are *assuming* threads, which is another unsafe
assumption. We need to make sure to conform to the WSGI spec
regarding multi-process vs. multi-thread. People like me just aren't
going to be deploying their apps inside a multi-threaded server. It
should be easier in that case anyway, because then its one connection
per process :) So, you just use the processes' current transaction
instead of the thread's current transaction.
As for defaults, I still vote for request-per-transaction by
default. It is the absolute safest thing to do, in my opinion,
because any other decision is making assumptions about the
applications that people are writing with TurboGears, how they are
deploying it, etc.
The only other alternative that I can think of, is to automatically
realize when you need to run inside a transaction by having SQLObject
start one automatically when a create, update, or delete occurs and
then have TurboGears commit or rollback any open transactions at the
conclusion of a request depending on whether or not an "exceptional"
Exception occurred.
-- Jon