Reputation: 15080
This question compares SELECT...LOCK IN SHARE MODE
and SELECT...FOR UPDATE
. However, how are these 2 different from the bare SELECT
inside a transaction? The database is MariaDB, but MySQL answer should be fine too if there are no differences. Most importantly, I need the info in the context of avoiding DB deadlocks.
Upvotes: 1
Views: 1395
Reputation: 142453
Many deadlocks can be avoided; some cannot. There is no single technique to prevent all deadlocks.
FOR UPDATE
seems to be more useful than LOCK IN SHARE MODE
. (I would be interested to hear someone argue the contrary.)
The usual pattern seems to be:
BEGIN;
SELECT ... FOR UPDATE; -- use the columns fetched; lock the row(s)
-- Note: the locked rows may or may not actually be UPDATEd later
-- Note: FOR UDPATE prevents other connections from grabbing the same row(s)
UPDATE/DELETE/... -- those rows.
COMMIT;
But... Nothing above prevents the classic deadlock scenario:
BEGIN; -- connection 1
SELECT row 123 FOR UPDATE;
SELECT row 234 FOR UPDATE;
...
Versus
BEGIN; -- connection 1
SELECT row 234 FOR UPDATE;
SELECT row 123 FOR UPDATE; -- Note: locking order was swapped
...
Failing to do some form of SELECT ...LOCK/UPDATE
can easily lead to a "race condition", wherein two connections are acting on the same row(s) in inconsistent ways.
Another note: If you "lock" the same rows in the same order, then one connection may stall until the other lets go. (cf innodb_lock_wait_timeout
, which defaults to 50 seconds [an excessive amount of time, in my opinion])
(All of my discussion should apply to all versions of InnoDB/XtraDB in either MySQL or MariaDB.)
Upvotes: 2