Java Reference
In-Depth Information
thread1.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
thread2.start();
}
}
If you run the application, you will get the following result:
Thread 1_Prepare to check book stock
Thread 1
_
Book stock is 10
Thread 1
_
Sleeping
Thread 2
_
Prepare to increase book stock
Thread 2
_
Book stock increased by 5
Thread 2
_
Sleeping
Thread 1
_
Wake up
Thread 2
_
Wake up
Thread 2_Book stock rolled back
First, thread 1 read the book stock and then went to sleep. At that time, thread 1's transaction had
not yet been committed. While thread 1 was sleeping, thread 2 started and attempted to increase the
book stock. With the
READ_COMMITTED
isolation level, thread 2 would be able to update the stock value
that was read by an uncommitted transaction.
However, if thread 1 reads the book stock again, the value will be different from its first read.
This problem is known as
non-repeatable read
because a transaction may read different values for the
same field.
To avoid the non-repeatable read problem, you should raise the isolation level of
checkStock()
to
REPEATABLE_READ
.
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.REPEATABLE_READ)
public int checkStock(String isbn) {
...
}
}
If you run the application again, thread 2 won't be able to update the book stock until thread 1 has
committed the transaction. In this way, the non-repeatable read problem can be avoided by preventing
a transaction from updating a value that has been read by another uncommitted transaction.
Search WWH ::
Custom Search