You should use [SELECT ... LOCK IN SHARE MODE][1]. Why ? > SELECT ... LOCK IN SHARE MODE sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits. If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values. In your case, you could attempt this START TRANSACTION; SELECT ... LOCK IN SHARE MODE; INSERT INTO ... SELECT ... ; ROLLBACK; This would do two `SELECT` queries - First `SELECT` to lock the rows in the table you wish - Second `SELECT` to perform `INSERT INTO ... SELECT` Personally, I do not think you have to be this heavy-handed. Transaction isolation should be smart enough to pull off this atomic `SELECT` and use the same rows for the `INSERT`. I know I said ***`should be`*** which is why your are asking you question in the first place. Whether you do `INSERT INTO ... SELECT` as one command or in the heavy-handed manner I am proposing, the row table will be fully readable. **GIVE IT A TRY !!!** [1]: http://dev.mysql.com/doc/refman/5.6/en/innodb-locking-reads.html