Wrap energy decr in transaction
Some checks are pending
CI/CD Pipeline / lint-sast (push) Waiting to run
CI/CD Pipeline / deploy (push) Blocked by required conditions

This commit is contained in:
Michail Kostochka 2025-06-09 13:56:18 +03:00
parent 42ab9eb8f4
commit 2b0322d962

View File

@ -18,7 +18,7 @@ async def store(conn: Connection, click: Click) -> int:
async def delete_user_info(conn: Connection, user_id: int): async def delete_user_info(conn: Connection, user_id: int):
async with conn.transaction(): async with conn.transaction():
await conn.execute('DELETE FROM clicks WHERE user_id=$1', user_id) await conn.execute('DELETE FROM clicks WHERE user_id=$1', user_id)
await conn.execute('DELTE FROM users WHERE id=$1', user_id) await conn.execute('DELETE FROM users WHERE id=$1', user_id)
async def get_period_sum(conn: Connection, user_id: int, period: int) -> decimal.Decimal: async def get_period_sum(conn: Connection, user_id: int, period: int) -> decimal.Decimal:
@ -65,14 +65,15 @@ async def get_energy(conn: Connection, user_id: int) -> int:
async def decr_energy(conn: Connection, user_id: int, amount: int) -> Tuple[int, int]: async def decr_energy(conn: Connection, user_id: int, amount: int) -> Tuple[int, int]:
new_energy, spent = await conn.fetchrow(''' with conn.transaction('serializable'):
WITH energy_cte AS ( new_energy, spent = await conn.fetchrow('''
SELECT energy, (CASE WHEN energy < $2 THEN energy ELSE $2 END) AS delta FROM users WHERE id=$1 WITH energy_cte AS (
) SELECT energy, (CASE WHEN energy < $2 THEN energy ELSE $2 END) AS delta FROM users WHERE id=$1
UPDATE users AS u SET )
energy=u.energy - e.delta UPDATE users AS u SET
FROM energy_cte AS e energy=u.energy - e.delta
WHERE id=$1 FROM energy_cte AS e
RETURNING u.energy as new_energy, e.delta WHERE id=$1
''', user_id, amount) RETURNING u.energy as new_energy, e.delta
''', user_id, amount)
return new_energy, spent return new_energy, spent