3. createTransaction
createTransaction
allows for transactions that span across multiple services. Each operation specified when a transaction is created must resolve successfully for changes to be committed. It works much like optimistic UI updates: proceed on the assumption that each operation will succeed and if any operation fails, changes are rolled back.
Simply createTransaction
with your queries and execute them within resolve
via exec
:
const transaction = createTransaction({
order: {
queryFn: orderService.createOrder,
onSuccess: onSuccessCreateOrder,
onError: onErrorCreateOrder,
},
payment: {
queryFn: paymentService.createPayment,
onSuccess: onSuccessCreatePayment,
onError: onErrorCreatePayment,
},
});
const { order, payment } = await transaction.resolve(async () => {
const newOrder = await transaction.exec("order", {
user: "1234",
items: [],
});
const paymentReceipt = await transaction.exec("payment", { order });
return { order: newOrder, payment: paymentReceipt };
});
// With support for `AsyncDisposable`
const checkout = async () => {
await using transaction = createTransaction({
order: {
queryFn: orderService.createOrder,
onSuccess: onSuccessCreateOrder,
onError: onErrorCreateOrder,
},
payment: {
queryFn: paymentService.createPayment,
onSuccess: onSuccessCreatePayment,
onError: onErrorCreatePayment,
},
});
const newOrder = await transaction.exec("order", {
user: "1234",
items: [],
});
const paymentReceipt = await transaction.exec("payment", { order });
return { order: newOrder, payment: paymentReceipt };
};
Each operation must specify the following options:
-
queryFn
: Any function which must return aPromise
. ThequeryFn
will not be executed by directly, rather it will be executed viaexec
. In optimistic update terms, we perform the state change (but possibly with a flag or some kind of indication that the dust has not settled yet) and if any error occurs, the state change is either reverted or the flag is left as is to indicate that the dust will not be settling -
onSuccess
: Any function which must return aPromise
, though its return is not used.onSuccess
is invoked with the result ofqueryFn
at the end if all operations have succeeded -
onError
: Any function which must return aPromsie
, though its return is not used.onError
is invoked with either the result ofqueryFn
if it resolved successfully or the error thrown byqueryFn
if it rejects unsuccessfully
createTransaction
returns the following:
-
resolve
: operations must beexec
uted withinresolve
for changes to be committed. If there is support forusing
AsyncDisposable
thenexec
uting operations within resolve is optional and changes will be committed at the end of the scope.resolve
returns the result of its argument -
exec
: execute an operation, each operation is labelled andexec
picks the relevantqueryFn
for the specified operation and executes it with the given arguments.exec
returns the result ofqueryFn