Laravel Database Pesimistic Locking

 get()sharedLock()lockForUpdate()update()
SELECT…OKOKOKOK
SELECT… LOCK IN SHARE MODEOKOKWAITWAIT
SELECT… FOR UPDATEOKWAITWAITWAIT
UPDATE…, DELETE…OKWAITWAITWAIT
MariaDB 10
idnamebalance
1Anto25,000
2Budi80,000
Table: wallets

CASE #1

MariaDB (connection1) > START TRANSACTION;
MariaDB (connection1) > SELECT * FROM wallets WHERE id=1;
idnamebalance
1Anto25,000
Result for connection1
MariaDB (connection2) > UPDATE wallets SET balance=30000 WHERE id=1;
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
idnamebalance
1Anto30,000
Result for connection2

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;
idnamebalance
1Anto25,000
Result for connection1

Connection #1 does not know that the balance of user 1 already changed.

MariaDB (connection1) > SELECT * FROM wallets WHERE id=1;
idnamebalance
1Anto30,000
Result for connection1

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;
idnamebalance
1Anto25,000
Result for connection1
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
idnamebalance
1Anto25,000
Result for connection2
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1 LOCK IN SHARE MODE;
idnamebalance
1Anto25,000
Result for connection2
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;
idnamebalance
1Anto25,000
Result for connection1
MariaDB (connection2) > SELECT * FROM wallets WHERE id=1;
idnamebalance
1Anto25,000
Result for connection2
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.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *