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

Reply via email to