Spring Transaction屬性之Isolation

上一篇博客《Spring Transaction屬性之Propagation》講解了Propagation相關的知識,這篇博客主要關注於Isolation這個屬性。


一、Isolation基礎

請先移步Wikipedia:isolation.

Isolation Level VS Phenomena


上圖來自wikipeida。

因爲我們在申明Isolation Level時,我們僅僅關心什麼Phenomena不會出現。所以,在SQL標準中,僅僅規定了Isolation Level會保證哪種讀現象不會出現,而不會規定某種讀現象一定會出現。

例如,在Isolation設置爲Repeatable Read時,不會出現Dirty Read。但是可能會出現Phantoms。如在Postgres中,Repeatable Read的效果就等同於Serializable,而在其他的數據庫,如DB2中,Repeatable Read會出現Phantom Read。


二、Isolation例子

Isolation本身前面的wikipedia的鏈接已經講的很清楚了,這裏我們用Spring Transaction來重現一個Phantom Read的情況。大家感受一下就行了。

假設我們有一張表叫User,User的id是主鍵。UserService提供瞭如下兩個方法:


    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void insertData() {
        jdbcTemplate.update("insert into User (id, username, age) values (123, 'xxx', 19)");
        doSleep(20000);
    }


    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void readRange() {
        System.out.println(jdbcTemplate.queryForList("select * from User where uses > 18").size());
        doSleep(40000);
        System.out.println(jdbcTemplate.queryForList("select * from User where uses > 18").size());
    }


如果我們同時執行這兩個方法:那麼insertData中的SQL會在兩次Query之間執行,於是readRange的兩次結果就會相差一。如果將READ_COMMITTED改爲了REPEATABLE_READ,則兩次結果會相同。


問題:如果我們的兩個方法的Transaction Isolation聲明不同,我們應該“聽”哪一個的呢?如上面的例子,我們把任意一個改成SERIALIZABLE後,會出現什麼樣的結果呢?


三、Isolation加強版

下面是何登成的博客,有些關於加鎖與Isolation之間關係的分析,很值得一讀:

http://hedengcheng.com/?p=771


四、Isolation的實現

常見的實現包括加鎖和MVCC(Multi Version Consistency Control),更多的參考資料,移步:

http://coolshell.cn/articles/6790.html

http://en.wikipedia.org/wiki/Multiversion_concurrency_control

http://wiki.postgresql.org/wiki/Serializable

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章