我试图了解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将能够读取更新的值。但事实并非如此。有人可以让我知道我哪里出错吗?
提前致谢!
答案 0 :(得分:2)
这里的问题是我从另一个事务方法(BookShop的方法)调用DAO的事务方法。
由于我没有为BookShop方法指定隔离级别,因此默认隔离级别为Isolation.READ_COMMITTED。
另请注意,我没有为Dao的方法指定传播行为,默认行为是Propagation.REQUIRED。因此,dao方法使用与BookShop相同的交易。因此,Isolation.READ_COMMITTED的隔离将应用于事务。
解决方案是:将BookShop方法的隔离级别指定为READ_UNCOMMITTED