Its one of the coolest things in Oracle
- readers do not block writers
- writers do not block readers
When we start a query, we record the "current moment in time" (its not actually "time", its the SCN, but time will do for this explanation). As we read the blocks needed, we make sure that they are not more recent than this moment. If they are, it means they were updated after our query began, and hence not appropriate for us to use in our query.
When we encounter such a block, we'll take a copy it in memory, and then wit this copy, we'll "rollback" the change(s) on that block until it has gone far enough "back in time" so that it represents the data as it was when our query began. Then we can use the rows in it, and move on. Notice I havent mentioned committed/uncommitted here. It doesn't really matter - even if an update has been committed, if it started after our query began, we'll still roll it back to get a consistent view of the block
The Concepts guide is a strongly recommended reading guide here
https://docs.oracle.com/database/121/CNCPT/consist.htm#CNCPT020