noob help : transaction not acid
sending two req at the same time, one with +10 the other with +100, the expected behavior for the trasnaction to wait for previous req to complete so its consistent
19 Replies
You are capturing the user object in this transaction, then waiting 5 seconds to add that value to the database.
The 2nd query comes in and does the same thing.
After 10 requests, the last query will have the final update:
user.usd
would be $0 + 100 = $100
That's not how you increment db values
is that postgres?
U'd want to do something like: "sqlSET usd = usd + ${value}
"I’m using Postgres yah, What if I need to do logic on user balance ? The read request should also be acid too I thought
I think you might be conflating two ideas here.
they are acid, it sounds like an application layer problem
how do i make sure the read also the latest, and wait if a transactions in progress ?
that's something that the db handles, eg if there are 2 concurrent request writing to the same table/col... pg will lock one and wait for it to be finished before the 2nd request can write to it.
the db is doing exactly what it needs to do, your business logic is faulty
...
what would u recommend?
To fix your current logic
thx
but i really need read modify write
isn't that wat your transaction is doing
nope
i could have some insane logic before write, that requires me to have the latest value for usd
this looks like its working, without using isolation lv of serailize which wants me to implement retry handling
again, doing
user.usd + val
will set an old value
what happens if the usd
value got updated some time between 1 and 5 seconds?
your user.usd
would be outdatedi passed for('update'), i think its locking that row/column and actually waits for it to finish
change the timeout to 1 minute
run your script
then go into your db console and change the value
will it allow you to update the value via console or cli due to that flag?
ok let me see
yep
it literally waited an entire minute
well i learned something new 2day
This can help to find the best way for your needs: https://www.2ndquadrant.com/en/blog/postgresql-anti-patterns-read-modify-write-cycles/
craig.ringer
2ndQuadrant | PostgreSQL
PostgreSQL anti-patterns: read-modify-write cycles
Shaun Thomas’s recent post about client-side loops as an SQL anti-pattern is well worth a read if you’re relatively new to SQL-based application development. It’s reminded me of another SQL coding anti-pattern that I see quite a lot: the naïve read-modify-write cycle. Here I’ll explain what this common development mistake is, how to identify it,...
“Row level locking with SELECT ... FOR UPDATE”
My code is doing that right? Just to make sure I’m not doing it wrong
It seems yes
you can log the executed query to be sure, but I guess it does
i have a question, the docs do this
does this do row locking if multiple request for that code gets run at the same time?
because its not locking accounts with for update
Yes 👍