Rollback not happening on tx.rollback() [PG DRIVER]

export async function createRestaurantMenuMutation({
label,
type,
availabilityDate,
categories,
}: CreateRestaurantMenuProps) {
let error: string | undefined;

try {
await db.transaction(async (tx) => {
const createMenu = await db
.insert(menus)
.values(restaurantMenuParse.data)
.returning()
.execute();

if (!createMenu[0]) {
error = "Não foi possível criar o menu.";
tx.rollback();
}

categories.forEach(async (category) => {
const categoryParse =
await createMenuCategorySchema.safeParseAsync({
...category,
});

if (!categoryParse.success) {
console.error(
"Error parsing category: ",
categoryParse.error,
);
error = "Existe um erro nos dados inseridos.";
tx.rollback();
}

const createCategory = await tx
.insert(menuCategories)
.values({
name: category.name,
menuId: createMenu[0]!.id,
})
.returning()
.execute();

if (!createCategory[0]) {
error = `Ocorreu um erro a criar a categoria ${category.name}. `;
tx.rollback();
}
});
return {
...createMenu[0],
categories,
};
});
} catch (e) {
console.log("Exception creating menu: ", { e });
throw new Error(error);
}
}
export async function createRestaurantMenuMutation({
label,
type,
availabilityDate,
categories,
}: CreateRestaurantMenuProps) {
let error: string | undefined;

try {
await db.transaction(async (tx) => {
const createMenu = await db
.insert(menus)
.values(restaurantMenuParse.data)
.returning()
.execute();

if (!createMenu[0]) {
error = "Não foi possível criar o menu.";
tx.rollback();
}

categories.forEach(async (category) => {
const categoryParse =
await createMenuCategorySchema.safeParseAsync({
...category,
});

if (!categoryParse.success) {
console.error(
"Error parsing category: ",
categoryParse.error,
);
error = "Existe um erro nos dados inseridos.";
tx.rollback();
}

const createCategory = await tx
.insert(menuCategories)
.values({
name: category.name,
menuId: createMenu[0]!.id,
})
.returning()
.execute();

if (!createCategory[0]) {
error = `Ocorreu um erro a criar a categoria ${category.name}. `;
tx.rollback();
}
});
return {
...createMenu[0],
categories,
};
});
} catch (e) {
console.log("Exception creating menu: ", { e });
throw new Error(error);
}
}
I've tried a couple different approachs (throwing errors etc, keeps the same issue)
3 Replies
RUNNb
RUNNbOP2mo ago
Also tried without try catch
Angelelz
Angelelz2mo ago
The first query inside the transaction uses the db object, basically bypassing the transaction and running the query in a different connection. You have to use the tx object passed to the callback. Also, I'm not sure how smart is it to pass an async function to forEach. I would advice to use for await (const category of categories) The async callback passed to forEach is very likely running in a different async context to the transaction, so if an error gets thrown, that call back doesn't know about it. Furthermore, throwing inside, probably doesn't reach to the transaction callback Worst of all, the transaction callback is probably returning before the forEach even gets a chance to be called
RUNNb
RUNNbOP2mo ago
Thank you, I actually just learned about the async callback!
Want results from more Discord servers?
Add your server