From 676bd7a9784bdbdd9cd822297d4009a35560a4bd Mon Sep 17 00:00:00 2001 From: MasterGordon Date: Tue, 10 Mar 2026 18:54:33 +0100 Subject: [PATCH] fixed possible race condition when paying with gems --- backend/repositories/gemsRepository.ts | 42 +++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/backend/repositories/gemsRepository.ts b/backend/repositories/gemsRepository.ts index 36693a8..4b32885 100644 --- a/backend/repositories/gemsRepository.ts +++ b/backend/repositories/gemsRepository.ts @@ -18,17 +18,21 @@ export const addGems = async ( user: string, gems: number, ) => { - const { count, totalCount } = await getGems(db, user); - if ((await db.select().from(Gems).where(eq(Gems.user, user))).length === 0) { - await db - .insert(Gems) - .values({ user, count: count + gems, totalCount: totalCount + gems }); - return; - } - await db - .update(Gems) - .set({ count: count + gems, totalCount: totalCount + gems }) - .where(eq(Gems.user, user)); + await db.transaction(async (tx) => { + const res = (await tx.select().from(Gems).where(eq(Gems.user, user)))[0]; + const count = res?.count ?? 0; + const totalCount = res?.totalCount ?? 0; + if (!res) { + await tx + .insert(Gems) + .values({ user, count: count + gems, totalCount: totalCount + gems }); + return; + } + await tx + .update(Gems) + .set({ count: count + gems, totalCount: totalCount + gems }) + .where(eq(Gems.user, user)); + }); }; export const removeGems = async ( @@ -36,10 +40,14 @@ export const removeGems = async ( user: string, gems: number, ) => { - const { count, totalCount } = await getGems(db, user); - if (count - gems < 0) throw new Error("Not enough gems"); - await db - .update(Gems) - .set({ count: count - gems, totalCount: totalCount }) - .where(eq(Gems.user, user)); + await db.transaction(async (tx) => { + const res = (await tx.select().from(Gems).where(eq(Gems.user, user)))[0]; + const count = res?.count ?? 0; + const totalCount = res?.totalCount ?? 0; + if (count - gems < 0) throw new Error("Not enough gems"); + await tx + .update(Gems) + .set({ count: count - gems, totalCount: totalCount }) + .where(eq(Gems.user, user)); + }); };