Java Reference
In-Depth Information
If you run the application, you will get the following result:
Thread 1_Prepare to increase book stock
Thread 1
_
Book stock increased by 5
Thread 1
_
Sleeping
Thread 2
_
Prepare to check book stock
Thread 2
_
Book stock is 15
Thread 2
_
Sleeping
Thread 1
_
Wake up
Thread 1
_
Book stock rolled back
Thread 2_Wake up
First, thread 1 increased the book stock and then went to sleep. At that time, thread 1's transaction
had not yet been rolled back. While thread 1 was sleeping, thread 2 started and attempted to read the
book stock. With the
READ_UNCOMMITTED
isolation level, thread 2 would be able to read the stock value that
had been updated by an uncommitted transaction.
However, when thread 1 wakes up, its transaction will be rolled back due to a
RuntimeException
,
so the value read by thread 2 is temporary and invalid. This problem is known as
dirty read
, because a
transaction may read values that are
"
dirty.
"
To avoid the dirty read problem, you should raise the isolation level of
checkStock()
to
READ_COMMITTED
.
package com.apress.springenterpriserecipes.bookshop.spring;
...
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
public class JdbcBookShop extends JdbcDaoSupport implements BookShop {
...
@Transactional(
isolation = Isolation.READ_COMMITTED)
public int checkStock(String isbn) {
...
}
}
If you run the application again, thread 2 won't be able to read the book stock until thread 1 has
rolled back the transaction. In this way, the dirty read problem can be avoided by preventing a
transaction from reading a field that has been updated by another uncommitted transaction.
Search WWH ::
Custom Search