In MySQL, SELECT FOR UPDATE is used to prevent lost update and write skew. *In MySQL, only SERIALIZABLE can prevent lost update and write skew without SELECT FOR UPDATE but deadlock error occurs so we should use SELECT FOR UPDATE even for SERIALIZABLE. You can know more about lost update and write skew in my answer of 'Lost update' vs 'Write skew'.
Now in MySQL, I'll show you lost update and write skew and how to prevent them with SELECT FOR UPDATE in REPEATABLE READ.
First, this is the example of lost update below. There is product table with id, name and stock as shown below.
product table:
| id | name | stock | 
| 1 | Apple | 10 | 
| 2 | Orange | 20 | 
 
These steps below shows lost update without SELECT FOR UPDATE in MySQL. *The stocks of the products decrease when customers buy the products:
| Flow | Transaction 1 (T1) | Transaction 2 (T2) | Explanation | 
| Step 1 | BEGIN; |  | T1 starts. | 
| Step 2 |  | BEGIN; | T2 starts. | 
| Step 3 | SELECT stock FROM product WHERE id = 2;
 20
 |  | T1 reads 20which is updated later to13because a customer buys 7 oranges. | 
| Step 4 |  | SELECT stock FROM product WHERE id = 2;
 20
 | T2 reads 20which is updated later to16because a customer buys 4 oranges. | 
| Step 5 | UPDATE product SET stock = '13' WHERE id = 2; |  | T1 updates 20to13. | 
| Step 6 | COMMIT; |  | T1 commits. | 
| Step 7 |  | UPDATE product SET stock = '16' WHERE id = 2; | T2 updates 13to16after T1 commits. | 
| Step 8 |  | COMMIT; | T2 commits. 
 
 *Lost update occurs. | 
 
Next, these steps below shows how to prevent lost update with SELECT FOR UPDATE on MySQL. *The stocks of the products decrease when customers buy the products:
| Flow | Transaction 1 (T1) | Transaction 2 (T2) | Explanation | 
| Step 1 | BEGIN; |  | T1 starts. | 
| Step 2 |  | BEGIN; | T2 starts. | 
| Step 3 | SELECT stock FROM product WHERE id = 2 FOR UPDATE;
 20
 |  | With "SELECT FOR UPDATE", T1 reads 20which is updated later to13because a customer buys 7 oranges. | 
| Step 4 |  | SELECT stock FROM product WHERE id = 2 FOR UPDATE; | T2 needs to wait for T1 to commit to read stockwith "SELECT FOR UPDATE". | 
| Step 5 | UPDATE product SET stock = '13' WHERE id = 2; | Waiting... | T1 updates 20to13. | 
| Step 6 | COMMIT; | Waiting... | T1 commits. | 
| Step 7 |  | SELECT stock FROM product WHERE id = 2 FOR UPDATE;
 13
 | Now with "SELECT FOR UPDATE", T2 reads 13which is updated later to9because a customer buys 4 oranges. | 
| Step 8 |  | UPDATE product SET stock = '9' WHERE id = 2; | T2 updates 13to9after T1 commits. | 
| Step 9 |  | COMMIT; | T2 commits. 
 
 *Lost update doesn't occur. | 
 
Second, this is the example of write skew. There is event table with name and user as shown below.
event table:
| name | user | 
| Make Sushi | John | 
| Make Sushi | Tom | 
 
These steps below shows write skew without SELECT FOR UPDATE in MySQL. *Only 3 users can join the event "Make Sushi":
| Flow | Transaction (JT) | Transaction (LT) | Explanation | 
| Step 1 | BEGIN; |  | T1 starts. | 
| Step 2 |  | BEGIN; | T2 starts. | 
| Step 3 | SELECT count(*) FROM event WHERE name = 'Make Sushi';
 2
 |  | T1 reads 2so only one user can join it. | 
| Step 4 |  | SELECT count(*) FROM event WHERE name = 'Make Sushi';
 2
 | T2 reads 2so only one user can join it. | 
| Step 5 | INSERT INTO event values ('Make Sushi', 'Lisa'); |  | T1 inserts Lisatoeventtable. | 
| Step 6 | COMMIT; |  | T1 commits. | 
| Step 7 |  | INSERT INTO event values ('Make Sushi', 'Kai'); | T2 inserts Kaitoeventtable. | 
| Step 8 |  | COMMIT; | T2 commits. 
 
 4 users join it.*Write skew occurs. | 
 
Next, these steps below shows how to prevent write update on MySQL with SELECT FOR UPDATE. *Only 3 users can join the event "Make Sushi":
| Flow | Transaction (JT) | Transaction (LT) | Explanation | 
| Step 1 | BEGIN; |  | T1 starts. | 
| Step 2 |  | BEGIN; | T2 starts. | 
| Step 3 | SELECT count(*) FROM event WHERE name = 'Make Sushi' FOR UPDATE;
 2
 |  | With "SELECT FOR UPDATE", T1 reads 2so only one user can join it. | 
| Step 4 |  | SELECT count(*) FROM event WHERE name = 'Make Sushi' FOR UPDATE; | T2 needs to wait for T1 to commit to read eventtable with "SELECT FOR UPDATE". | 
| Step 5 | INSERT INTO event values ('Make Sushi', 'Lisa'); | Waiting... | T1 inserts Lisatoeventtable. | 
| Step 6 | COMMIT; | Waiting... | T1 commits. | 
| Step 7 |  | SELECT count(*) FROM event WHERE name = 'Make Sushi' FOR UPDATE;
 3
 | Now with "SELECT FOR UPDATE", T2 reads 3so no users can join it. | 
| Step 8 |  | COMMIT; | T2 commits. 
 
 3 users join it.*Write skew doesn't occurs. |