Your cart is currently empty!
Laravel Database Pesimistic Locking
get() | sharedLock() | lockForUpdate() | update() | |
SELECT… | OK | OK | OK | OK |
SELECT… LOCK IN SHARE MODE | OK | OK | WAIT | WAIT |
SELECT… FOR UPDATE | OK | WAIT | WAIT | WAIT |
UPDATE…, DELETE… | OK | WAIT | WAIT | WAIT |
id | name | balance |
1 | Anto | 25,000 |
2 | Budi | 80,000 |
… | … | … |
CASE #1
MariaDB (connection1) > START TRANSACTION;
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > UPDATE wallets SET balance=30000 WHERE id=1;
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
id | name | balance |
1 | Anto | 30,000 |
Connection #2 is updating the balance of user 1. The change reflects on connection #2 but does not reflect for connection #1 (which hangs in the middle of transaction).
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1;
MariaDB (connection1) > COMMIT;
id | name | balance |
1 | Anto | 25,000 |
Connection #1 does not know that the balance of user 1 already changed.
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1;
id | name | balance |
1 | Anto | 30,000 |
Connection #1 figures out that the balance already changed after ending the transaction.
In the case connection #1 updating the balance of user 1 before connection #2, connection #2 will wait until connection #1 do the commit and then continue to run the update from connection #2 (which replaces the recently updated balance from connection #1). The end result is the balance set from update by connection #2.
CASE #2
MariaDB (connection1) > START TRANSACTION;
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1 LOCK IN SHARE MODE;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1 LOCK IN SHARE MODE;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1 FOR UPDATE;
The above statement will not execute until connection1 is doing commit
or rollback
.
MariaDB (connection2) > UPDATE wallets SET balance=30000 WHERE id=1;
The above statement will not execute until connection1 is doing commit
or rollback
.
CASE #3
MariaDB (connection1) > START TRANSACTION;
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1 FOR UPDATE;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
id | name | balance |
1 | Anto | 25,000 |
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1 LOCK IN SHARE MODE;
The above statement will not execute until connection1 is doing commit
or rollback
.
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1 FOR UPDATE;
The above statement will not execute until connection1 is doing commit
or rollback
.
MariaDB (connection2) > UPDATE wallets SET balance=30000 WHERE id=1;
The above statement will not execute until connection1 is doing commit
or rollback
.
Leave a Reply