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 Lassi Kortela 18 Sep 2019 08:26 UTC

> I just didn't want to require the user throwing and catching an exception
> just to abort the transaction.

This possibility didn't occur to me. I understand your aversion to it :)

> Perhaps we can specify a specific exception type to throw which will just
> return from the with-transaction but not propagate the exception to user
> code?  That would probably be the better API, in hindsight.  Any other type
> of exception will be re-raised, just not this one.

This is the approach I meant. IIRC many DB APIs in other languages do this.

> Alternatively, we could have a specific procedure that aborts the current
> transaction and calls the continuation of the with-transaction call.
> This could be implemented using the mechanism I just described without
> exposing that it's actually an exception.  That would be even less ugly
> at the cost of adding another procedure to the API.

This is probably a good idea as well. IIRC many DB APIs have a
"rollback" procedure that probably just raises a magic exception.

>> 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.
>
> Well, I think you just described that yourself: if a library wants to
> abort its own transaction, it should not roll back the entire user
> transaction.  That's the idea behind nested transactions: it's an
> abstraction.  It's somewhat leaky due to the isolation levels not being
> changeable, but other than that I think it's best to make use of
> savepoints when available.

You're right. This didn't occur to me.

> The real question is: what should we do with nested with-transaction
> calls for engines that don't support them?  We could raise an exception,
> but that would make such library code unusable.  Alternatively, we could
> just ignore the nesting but that would change the semantics when the
> library tries to do a rollback; it would either do nothing (which is
> undesirable) or it would abort the user transaction completely (which is
> probably not what was intended either).

As with the URL stuff in Schemeweb, I'm glad we have your experience on
board. This is much harder than it seemed at first :) No good ideas from
me at this time...

> Note that this is not a specific Postgres feature.  MySQL has savepoints
> as well: https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
> And so does SQLite: https://sqlite.org/lang_savepoint.html

It's nice to know that they're widely supported.

> Perhaps we should treat databases that don't support this as second-class
> and raise an exception when you try to roll back a nested transaction?
> That way, the "happy path" will always work.  Not sure this is great
> design, though.  Raising an exception when trying to make a nested
> transaction could also work, but that means some library code is
> completely unusable in certain databases (how many databases don't have
> these, anyway?).

Hard to say. I agree with your assessment that this is likely to
effectively throw other databases into the bin for Schemers :)
Eventually it'd be nice to download SQL-wielding Scheme libraries from a
package repository, and most of those could be expected to fail on
exotic DBs because of the nested transaction thing.