相關文檔:mybatis configurationhtml
相關代碼:githubgit
最近發現一個問題,當使用Spring Transaction的時候,發現對同一個sequence屢次調用nextval返回的結果相同。通過一番搜索發現此問題和mybatis local cache有關。github
在繼續探討這個問題以前,先搞清楚mybatis的cache類型:spring
mybatis提供了兩種cache類型:local cache和cachesql
local cache,也就是所謂的局部緩存。由如下參數控制:數據庫
localCacheScope
,見相關文檔緩存
cache,也就是所謂的二級緩存。由如下參數控制:session
要特別注意的是,mybatis的local cache是沒法關閉的。
那麼local cache幹了什麼?在默認配置狀況下,mybatis會將同一session內的查詢結果都放在local cache中,這樣能夠提升性能,避免每次都hit到數據庫。
那麼cache幹了什麼呢?和local cache相對的,cache是跨session的,也就是說這個session中緩存的結果,在另一個session中也可以用到。
前面已經講到了在同一session中的查詢會將結果緩存,那麼這個和咱們一開始提到的問題有什麼關係呢?聰明的你必定已經想到了,這個問題和啓用了事務有關。
實際上mybatis在和spring集成後,會自動將session綁定到事務上,那麼就會產生前面提到的問題。
有如下幾種解決辦法:
在mybatis配置文件中localCacheScope=STATEMENT
。
在mapper配置文件中,給select設置flushCache=true
。須要注意的是,這樣會將local cache和cache都清空掉。
不用事務
NativeTest:說明在使用SqlSession時,local cache的做用
NoTxTest:說明在無事務時,local cache的做用
TxTest:說明在有事務時,local cache的做用