user652649
user652649

Reputation:

Do I need (will I ever need) LOCK IN SHARED MODE | FOR UPDATE within a transaction?

I'm painfully struggling trying to understand how to write best my code and queries

straight to the question: do I need or will I ever need to write explicitly LOCK IN SHARED MODE or FOR UPDATE in a transaction (apart from READ UNCOMMITTED ones)?

if I have external keys, do I need to select rows explicitly to apply the lock to these rows, or the foreign keys definition is enough?

Upvotes: 5

Views: 783

Answers (1)

Mehran
Mehran

Reputation: 16891

The short answer: absolutely yes.

The complete answer: it depends on the use case. Perhaps in the most of scenarios the default locks used by InnoDb is sufficient. These locks make sure that your data is consistent within a transaction. But here's a scenario that needs a lock using SELECT ... FOR UPDATE:

Consider you are making a web application in which your session data is stored in database. Race condition is a concern when it comes to session data. While this concern is satisfied when files are used to store session data, but if you move them to database it's your duty to make sure requests won't overwrite each other's session changes. In this scenario you need to read session data from MySQL using FOR UPDATE to make sure other requests will wait for this one to write back the session and commit the transaction before they could read it.

[UPDATE]

Here's a use case for shared mode:

Shared mode is useful when you want to make sure that some record remains unchanged to the end of your transaction. e.g. when you are trying to insert a child record with a foreign key to a parent when the parent record has been inserted in previous transactions. In this case you will first select the parent record locked in shared mode and then try to insert the child to make sure that when you are inserting the child, parent still exists. This way other sessions can still read the parent record but no one can change it. That's just off the top of my mind, but in the all use cases of shared mode lock this fact remains the same that you want a record to remain unchanged while it's still accessible for others to read.

[UPDATE]

Regarding the transaction isolation level of SERIALIZABLE, the MySQL's documentation is pretty clear. If you set the transaction level this way, and also SET autocommit = 0;, then it's exactly like the REPEATABLE READ level plus writing all your select queries with LOCK IN SHARE MODE at the end (unless you mention FOR UPDATE explicitly). It means everything you'll touch (explicitly or implicitly) will be locked. Those that are selected without any mention of locks or those with LOCK IN SHARED MODE are locked in shared mode, and the rest in exclusive mode.

Upvotes: 4

Related Questions