If I remember correctly, transactions managed by the @tables.in_transaction
decorator are automatically retried with a random delay a number of times, maybe 5. Well, the whole function is automatically retried.
Using the transaction context manager instead, you have control about what to do when there is a failure.
I usually have:
- one read only transaction at the beginning to collect the required data
- after closing the transaction, work on the time expensive logic
- create a second transaction
- read the same data to check that nothing has changed
- if something has changed, restart
- if nothing has changed write the results
This pattern ensures transactions are kept alive for the shortest time possible, and gives me full control on what and when to retry or bail out.