本文介绍了隔离级别READ_UNCOMMITTED不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解Spring事务的隔离级别.这是我正在使用的示例:

I am trying to understand isolation levels of Spring transactions. Here is the example I am using:

@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!");
    }

}

这就是我调用上述方法的方式:

And this is the way I am invoking the above:

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>

但是当我运行示例时,这是我得到的结果:

But when I run the example, here is the o/p I am getting:

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将能够读取更新后的值.但事实并非如此.有人可以让我知道我要去哪里了吗?

I thought Thread-3 will be able to read the updated value. But it is not. Can someone please let me know where I am going wrong?

预先感谢!

推荐答案

这里的问题是我正在从另一个事务方法(BookShop的方法)中调用DAO的事务方法.

The problem here is I am calling DAO's transactional methods from another transactional method(BookShop's methods).

由于我尚未为BookShop的方法指定隔离级别,因此默认隔离级别为Isolation.READ_COMMITTED.

As I have not specified the isolation level for BookShop's method, the default isolation level is Isolation.READ_COMMITTED.

还要注意,我没有为Dao的方法指定传播行为,默认行为是Propagation.REQUIRED.因此,dao方法使用与BookShop相同的事务.因此,将Isolation.READ_COMMITTED的隔离应用于事务.

Also note that I have not specified propagation behavior for Dao's method and the default behavior is Propagation.REQUIRED. Hence dao methods uses the same transaction as of BookShop's. So the isolation of Isolation.READ_COMMITTED gets applied for the transaction.

解决方法是:将BookShop方法的隔离级别指定为READ_UNCOMMITTED

Solution is: Specify the isolation level for BookShop methods as READ_UNCOMMITTED

这篇关于隔离级别READ_UNCOMMITTED不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 06:52