You can add FOR UPDATE to the select statement to block all rows it encounters.
But this is not enough - you basically need to lock the entire table (because you are going to update the whole table), and transactions will not do this for you. InnoDB has row-level locking, and only locked blocks of the desired rows, which will not work here, because you select only one row, but update everything.
Selecting the entire FOR UPDATE table to lock all rows may block everything, but it will work best with the first SELECT. Otherwise, you read one line and freeze your opinion (read continuously), and then another transaction does the same. Now both of you have the same look - but this second transaction really needs to read data that is about to change! (The second transaction will not be blocked - you read and block different rows. The system does not know that you plan to update the entire table.) Therefore, if you lock in this way (FOR UPDATE), this statement should be one in order to βfreezeβ your view to the table.
After some research, I decided that the only possible solution is advisory locking.
(The normal LOCK command in MySQL does not work with transactions.)
Instead, use the GET_LOCK function - and run it before opening a transaction, not after.
i.e.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT GET_LOCK('folders_nested_set', <timeout>); START TRANSACTION WITH CONSISTENT SNAPSHOT; do work on folders table here COMMIT; DO RELEASE_LOCK('folders_nested_set');
Make sure that all functions that work with the nested set are wrapped in a transaction. Not for writing, but to ensure consistent reading in SQL queries.
i.e.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION WITH CONSISTENT SNAPSHOT; do reads here COMMIT;
If you do not know that you are reading all the data that you need in only one SQL statement, you do not need it.
(You can run SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ immediately after you connect to db, not each transaction. Be sure to include the SESSION keyword in this case.)
If I am mistaken or missed something here - or even if there is a better way, I would really like to know about it, because I am dealing with exactly the same situation.