Re: How to do transactions, especially nested
Lassi Kortela 18 Sep 2019 07:41 UTC
> Usually you'll only want to roll back when an exception occurs. If you
> want to explicitly roll back, you can just return #f from the thunk which
> should be rolled back.
Is returning true/#f a good interface in practice? I used that kind of
interface in some other language (Python or Ruby perhaps) and it was
difficult to track down bugs where you didn't realize that return value
was significant.
Are there problems with committing the transaction by default, but
rolling back if an unhandled exception is raised inside the
"with-transaction" bloc?
> In my experience, you don't tend to
> have that many nested transactions. Usually, you have one big outer
> transaction and that's it.
I agree. Nested transactions happen when some of the code is in a
library (or a separate module of the application) so that it doesn't
know whether or not it's inside a transaction, and uses
"with-transaction" to make sure it is.
So when reading the code of any particular library or module, you'll
generally find only one level of nesting. Combining calls from several
modules causes the nested transactions behind the scenes.
For this purpose, transactions also do not need to be nested on the
database side. It's enough for Scheme to keep a "reference count" of how
many transactions deep we are, and just create a DB engine transaction
at the outermost level and commit/rollback at the outermost level.
There are probably some exotic situations where you'd want to use those
Postgres savepoints at the DB engine side to rollback only part of a
transaction. I don't know anything about that; I'll let you decide.
> I don't see this is very different from with-input-from-port (which
> I consider super-Schemely because it's in the standard), or in my
> http-client library with-input-from-request.
This is pretty typical Scheme style in my experience too. Harold, can
you post an example of ugly code?
It helps a lot in Emacs if you indent the code so the (lambda ...) is
only two spaces deep (as though it were a macro body).
> Let's please avoid macros unless absolutely necessary! Macros don't
> compose, but procedures do.
I'm neutral on this. If there's a macro, it may be good to include an
equivalent procedure just in case.