Transactions are supposed to be run concurrently. The isolation level specifies how much the transactions will influence each other.
Campbell is right that if two transactions decide to modify the same data (usually it is the same row in the database table), the second transaction will have to wait until the first ends (commits or rolls back). This behavior isn't affected by the isolation level, and you generally don't have to care about it yourself (in your code). The database does the syncing. You still need to design things carefully, though, as in the database, as well as in your code when it uses the
synchronized keyword, a deadlock can occur.
So, what does isolation level do? Imagine two transactions running concurrently (at the same time). One of the transaction modifies certain row in a table, say, it changes the value of column
A from 10 to 20. And now the other transaction tries to read that value. The isolation level determines what the other will "see".
In
Read uncommited level (the lowest one), the other transaction will read a value of 20. However, it is not very good, since the first transaction might not actually commit, it might roll back, and then the correct value would be 10 - in a certain sense, the value 20 never existed in the database.
In
Read committed level (second lowest), the other transaction will read a value of 10 - the value that was there before the transaction started.
Good! Clearly that's what we wanted. So, what are the higher isolation levels for?
There's the
Repeatable reads isolation level. This ensures that the data in your transaction don't change. For example, say that during the other transaction a query was executed, which read the value of column
A, and it was 10. Then the first transaction changes the value to 20 and commits, and now the other transaction, for some reason, read the value of column
A again. In
Read committed level, you would get 20. That's unfortunate, because now you have two values of the same data and don't know which one was right. But with
Repeatable reads, you're guaranteed to read the value you obtained on your first query (in our case, 10), forever.
The strongest isolation level is
Serializable. This prevents one additional type of inaccuracy from occurring in transaction. Say that you've read all rows from a table in your transaction, and another transaction meanwhile inserts another row and committs. Then in your original transaction you'll re-read the contents of the table. In
Serializable isolation level, you'll get the same set of rows you got the first time. In lower isolation levels, the row inserted by another transaction will be read on your second attempt. So, it is similar to
Repeatable reads, but now it is extended to newly inserted rows as well.
Obviously, the
Serializable level is the best. Your queries will always return the same data, regardless of what other transactions in the database do. Why doesn't everybody just use
Serializable and forgets about all the other levels?
The isolation of transactions (now you may also understand why it is called "isolation level") comes at a cost. In some databases, it is ensured by locks. To ensure
Read committed, for example, a transaction that wants to read a row modified by another transaction will wait until the other transaction ends. And higher isolation levels require more locks, typically when a row is read by some transaction, it can't be modified until the reading transaction ends. And if the reading transaction generates some reports and spends many minutes reading data for that report, you can easily see that the concurrency in the database suffers. There are other databases that use different mechanism to comply with isolation levels - these databases are able to read the data as they looked in the past, before the modifications done by other transactions were done (so, they use far fewer locks, but sometimes a transaction can fail in them because it isn't possible to ensure the requested isolation level).
If you want to design or program database applications,
you should probably know about isolation levels. One of the best explanations I've encountered is
here. It deals with Oracle database in the second half, but the first half, where the isolation levels are explained, is true for databases in general.