current value. • Get the database to figure out the new value. Don't assume we know what the value is in advance. 2. Add conditions to the UPDATE. • Only update if our assumptions are true.
current value. • Get the database to figure out the new value. Don't assume we know what the value is in advance. 2. Add conditions to the UPDATE. • Only update if our assumptions are true. 3. Put everything inside a container. • Suddenly the container is the atom.
id = 123; UPDATE accounts SET balance = 10 WHERE id = 123; $a = Account::find(123); // Do something we can't // use SQL for. Let's // call it calculate(): $a-‐>balance = calculate($a-‐>balance); $a-‐>save(); // ^-‐-‐ This is broken.
calculate($a-‐>balance), ]); // ^-‐-‐ This is better. // => 1 means it worked // => 0 means it didn't -‐-‐ SELECT ... UPDATE accounts SET balance = 10 WHERE id = 123 AND balance = 5; 2) Add Conditions to UPDATE.
not?" counter is too coarse. • Can't differentiate between Stale and Gone. (Needs an extra SELECT round-trip, and we're starting to replicate features the database already gives us.) 2) Add Conditions to UPDATE.
123; UPDATE accounts SET balance = 9 WHERE id = 123; SELECT * FROM accounts WHERE id = 123; UPDATE accounts SET balance = 10 WHERE id = 123; A Still stomping all over A.
-‐>lockForUpdate() -‐>firstOrFail(); // SELECT ... FOR UPDATE // Locks row; anything else has to wait in // line until COMMIT is called. $a-‐>balance = calculation($a-‐>balance); $a-‐>save(); // UPDATEs, COMMITs // Other processes free to run a SELECT. Locks: SELECT FOR UPDATE