Transactions
Transactions are supported via the Transaction
class.
Creating a new transaction creates a new set of models whose queries will be run inside the transaction:
There are two ways of using transactions:
- with a callback function
- without a callback function
Transactions with a callback
All queries to be run inside the transaction are wrapped in a callback function:
Instead of calling Transaction.prototype.execute
, you can also simply await
the Transaction
instance:
The transaction will be automatically committed if the callback function resolves successfully, otherwise it will be rolled back.
Transactions without a callback
note Transaction.prototype.commit
must be called when it's
time to commit the transaction.
info
If there is any error while running a query, the transaction will be automatically rolled back before the query that failed is rejected:
the second
User.insert
will be rejected with anQuery.InsertError
and the transaction will be rolled back, such that no rows will end up being inserted.
To ensure transactions are rolled back due to other errors besides query errors,
use a try..catch
(or Promise.prototype.catch
) and call
Transaction.prototype.rollback
if an error occurs:
Running queries inside other methods within transactions
If you have instance methods that run nested queries using other models, access
those models via Model.prototype.models
(or Model.models
in static methods)
to ensure that those queries are run within transactions.
info
In transactions, the model regstry is replaced with a new set of models whose queries run inside a transaction. Therefore, the same code inside those methods will not require any changes for the queries to run inside transactions.
For example, with this setup:
To get a group's users, you would do something like:
In this case, the queries are sent normally, i.e. not within a transaction. To run the same queries within a transaction:
Without having to change the implementation of Group.prototype.getUsers
at
all.
For this reason, when using models in instance and static methods, it's
recommended to always access models via the model
registry instead of requiring them with
Node's require
method.
Running queries with transaction models after transactions are ended
note
When transactions are ended, it's still possible to run queries with transaction models. However, those queries will not run inside a transaction:
The same holds true for transactions with a callback: