How to do transactions, especially nested hga@xxxxxx (18 Sep 2019 01:22 UTC)
Re: How to do transactions, especially nested Peter Bex (18 Sep 2019 06:05 UTC)
Re: How to do transactions, especially nested Lassi Kortela (18 Sep 2019 07:41 UTC)
Re: How to do transactions, especially nested Peter Bex (18 Sep 2019 07:58 UTC)
Re: How to do transactions, especially nested Lassi Kortela (18 Sep 2019 08:26 UTC)
Re: How to do transactions, especially nested Alaric Snell-Pym (18 Sep 2019 10:27 UTC)
Re: How to do transactions, especially nested Alaric Snell-Pym (18 Sep 2019 10:26 UTC)
Re: How to do transactions, especially nested hga@xxxxxx (18 Sep 2019 15:54 UTC)

Re: How to do transactions, especially nested Peter Bex 18 Sep 2019 06:05 UTC
On Tue, Sep 17, 2019 at 08:21:52PM -0500, xxxxxx@ancell-ent.com wrote:
> > You can also rollback the innermost savepoint s2 without also
> > rolling back s1 or the surrounding "proper" transaction.  So as far
> > as I'm concerned, these semantics are a perfect fit for a nested
> > "with-transaction" operator.
>
> So you'd do it like http://wiki.call-cc.org/eggref/5/postgresql

Right, that's one part of the API I like a lot.

> > (with-transaction CONN THUNK [isolation: LEVEL] [access: MODE])
>
> > Execute THUNK within a BEGIN TRANSACTION block, and return the value
> > of thunk.
>
> > The transaction is committed if thunk returns a true value. If an
> > exception occurs during thunk, or thunk returns #f, or the commit
> > fails, the transaction will be rolled back. If this rollback fails,
> > that is a critical error and you should likely abort.
>
> > Nested applications of with-transaction are supported -- only those
> > statements executed within THUNK are committed or rolled back by any
> > with-transaction call, as you would expect.
>
> Without looking at any code, what are the mechanics of rolling back an
> inner savepoint?  Do you execute a bare statement (ugly) and then
> return non-#f from the inner with-transaction's thunk?

I don't understand what you mean by "do you execute a bare statement".
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.  e.g.,

(with-transaction db
  (lambda ()
    (query db "INSERT INTO foo (bar, qux) VALUES (1, 2)")

    (with-transaction
      (lambda ()
        (query db "INSERT INTO foo (bar, qux) VALUES (3, 4)")
        ;; Oops, decide to roll this back
        #f))

    (query db "INSERT INTO foo (bar, qux) VALUES (5, 6)")))

When this returns, foo will contain the tuples 1,2 and 5,6.

> And I have to say that I really don't like the code style you get with
> naive use of this (with THUNK) paradigm, even before it gets nested.
> While making things very clear in one way, it's also very ugly, and it
> radically distinguishes the operations in the THUNKs compared to
> single ones which get by with auto-commit mode.  (Requiring the
> wrapping those with a (with-fake-transaction THUNK) will fix the
> distinguishing issue while making *everything* ugly.)

What exactly do you find so ugly?  In my experience, you don't tend to
have that many nested transactions.  Usually, you have one big outer
transaction and that's it.

> A further argument is that if my above partly aesthetic claim is
> correct, the ugly ceremony required will to an extent discourage the
> use of transactions, which would be bad....

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.  Maybe our personal
styles of how we write Scheme just differ?

> I suppose I want something that looks more like how you'd plainly
> write it out, but with with-transaction magic decorating it instead
> intermingling with BEGIN TRANSACTION etc. operations.
>
> Wouldn't fixing that calls for macro magic?  How much can and should
> we require (fancy?) macros in an SRFI?

Let's please avoid macros unless absolutely necessary!  Macros don't
compose, but procedures do.

Cheers,
Peter