In general, stuff that locks rows tends to "snap" values into existence regardless of repeatable read.
If you want to update a record based upon data in another record, you should do a locking read on that something else and maybe the record you're updating. If you run an sql query to update a record based upon some other record using a single query, MySQL will lock both for you anyways.
If you need to update something based upon multiple something elses, in my experience that's very deadlock prone. Instead you should lock some kinda locking record, then do a repeatable read on the data you want, then do an update.
The point in time of the repeatable read isn't established until you perform a consistent read. Select... for update isn't a consistent read. So it works perfectly fine in the face of concurrency while not locking dozens or hundreds of rows using a normal SQL update.
It kinda depends. I might do it like this if its super simple:
UPDATE A, B SET A.x = B.x where A.b_id = B.id and A.id = 1;
If it's more complex, it might have to be more like this:
SELECT * FROM A ... FOR UPDATE;
SELECT * FROM B... FOR SHARE;
UPDATE A...
If B is only ever updated after locking A, you can safely do this:
SELECT * FROM A ... FOR UPDATE;
SELECT * FROM B...;
UPDATE A...
Generally speaking, I wouldn't recommend locking "for share" then updating it later. This can result in deadlocks because you're upgrading it to an exclusive lock.
If you want to update a record based upon data in another record, you should do a locking read on that something else and maybe the record you're updating. If you run an sql query to update a record based upon some other record using a single query, MySQL will lock both for you anyways.
If you need to update something based upon multiple something elses, in my experience that's very deadlock prone. Instead you should lock some kinda locking record, then do a repeatable read on the data you want, then do an update.
The point in time of the repeatable read isn't established until you perform a consistent read. Select... for update isn't a consistent read. So it works perfectly fine in the face of concurrency while not locking dozens or hundreds of rows using a normal SQL update.