Skip to content

3. createTransaction

Naveen Mathew edited this page Mar 6, 2024 · 1 revision

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 };
};

Options

Each operation must specify the following options:

  • queryFn: Any function which must return a Promise. The queryFn will not be executed by directly, rather it will be executed via exec. 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 a Promise, though its return is not used. onSuccess is invoked with the result of queryFn at the end if all operations have succeeded

  • onError: Any function which must return a Promsie, though its return is not used. onError is invoked with either the result of queryFn if it resolved successfully or the error thrown by queryFn if it rejects unsuccessfully

Result

createTransaction returns the following:

  • resolve: operations must be executed within resolve for changes to be committed. If there is support for using AsyncDisposable then executing 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 and exec picks the relevant queryFn for the specified operation and executes it with the given arguments. exec returns the result of queryFn