Spring トランザクションの分離レベルを理解しようとしています。これが私が使用している例です:
@Component
public class BookShop {
private Object lockObj = new Object();
@Autowired
private BookDao bookDao;
@Transactional
public void increaseStock(int isbn, int increment){
String threadName = Thread.currentThread().getName();
synchronized (lockObj) {
Book book = bookDao.findByIsbn(isbn);
System.out.println(threadName+" about to increment the stock");
bookDao.updateStock(book, 5);
}
System.out.println(threadName+" has increased the stock ");
sleep(threadName);
System.out.println(threadName+" rolled back stock");
throw new RuntimeException("Stock increased by mistake");
}
@Transactional
public int checkStock(int isbn){
int stock = 0;
String threadName = Thread.currentThread().getName();
synchronized (lockObj) {
System.out.println(threadName+" checking for the stock");
stock = bookDao.getStock(isbn);
}
System.out.println(threadName+": Stock is: "+stock);
sleep(threadName);
return stock;
}
private void sleep(String threadName){
System.out.println(threadName+" sleeping");
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
}
System.out.println(threadName+" wakeup!");
}
}
そして、これは私が上記を呼び出す方法です:
public void testIsolationLevels(final BookShop bookShop, final int isbn){
Thread t1 = new Thread(){
public void run() {
bookShop.increaseStock(isbn, 5);
};
};
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
Thread t2 = new Thread(){
public void run() {
bookShop.checkStock(isbn);
};
};
t2.setPriority(Thread.MIN_PRIORITY);
t2.start();
}
そして、ここにトランザクション構成があります:
<tx:advice id="bookTxn" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="updateStock" isolation="READ_UNCOMMITTED"/>
<tx:method name="getStock" isolation="READ_UNCOMMITTED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.pramati.springIdol.dao.BookDao+.*(..))" id="bookPC"/>
<aop:advisor advice-ref="bookTxn" pointcut-ref="bookPC"/>
</aop:config>
しかし、この例を実行すると、次のような o/p が得られます。
Thread-2 about to increment the stock// Initially it is 99
Thread-2 has increased the stock // Now it is 104(99+5)
Thread-2 sleeping
Thread-3 checking for the stock
Thread-3: Stock is: 99//Why is it not 104 even if isolation level is read_uncommitted??
Thread-3 sleeping
Thread-2 wakeup!
Thread-2 rolled back stock
Thread-3 wakeup!
Exception in thread "Thread-2" java.lang.RuntimeException: Stock increased by mistake
Thread-3 は更新された値を読み取ることができると思いました。そうではありません。誰かが私が間違っているところを教えてもらえますか?
前もって感謝します!