← Back to context

Comment by AdieuToLogic

5 days ago

> The intent of the transaction code is that the consistency is checked (using `tx.commit()`) "even if an unexpected exception occurs".

First, having a `commit` unconditionally attempted when an exception is raised would surprise many developers. Exceptions in transactional logic are often used to represent a "rollback persistent store changes made thus far" scenario.

Second, using a condition within `finally` to indicate a retry due to a `commit` failing could be expressed in a clearer manner by having it within the `try` block as described by IntelliJ here[0].

0 - https://www.jetbrains.com/help/inspectopedia/ContinueOrBreak...

> Exceptions in transactional logic are often used to represent a "rollback persistent store changes made thus far" scenario.

Handling can be added to change the transaction to be read-only if the inner code throws a particular exception, but the consistency should still be checked through a `commit` phase (at least in an OCC setting), so the `continue` in `finally` is still the correct way to do it.

> could be expressed in a clearer manner by having it within the `try` block as described by IntelliJ here[0].

> 0 - https://www.jetbrains.com/help/inspectopedia/ContinueOrBreak...

Wrong link? The only solution I see there is to add a comment to suppress the warning, which sounds fine to me (eg, analogous to having a `// fallthrough` comment when intentionally omitting `break` statements within `switch`, since I can agree that both of these things are uncommon, but sometimes desirable).

  • > Handling can be added to change the transaction to be read-only if the inner code throws a particular exception, but the consistency should still be checked through a `commit` phase (at least in an OCC setting), so the `continue` in `finally` is still the correct way to do it.

    This approach fails to account for `fn` performing multiple mutations where an exception is raised from statement N, where N > 1.

    For example, suppose `fn` successfully updates a record in table `A`, then attempts to insert a record into table `B` which produces a constraint violation exception[0]. Unconditionally performing a `commit` in the `finally` block will result in the mutation in table `A` being persisted, thus resulting in an invalid system persistent state.

    If the `try` block performed the `commit` and the `finally` block unconditionally performed a `rollback`, then the behavior I believe sought would be sound.

    >> 0 - https://www.jetbrains.com/help/inspectopedia/ContinueOrBreak...

    > Wrong link?

    No, it's the link I intended. The purpose of it was to provide the warning anyone working in a translation unit using the technique originally proffered would see as well as be a starting point for research.

    0 - https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/...