循環中用相同條件重復查詢數據,並編輯查詢結果返回的集合,導致查詢結果重復 或者在事務里 修改結果集 導致查詢數據 結果集不是數據庫值
分析
- mybatis一級緩存默認開啟,重復查詢使用同一條SqlSession會重復從一級緩存中讀取數據
- 返回的集合對象是個List,在處理往list集合中插入數據,等同於往一級緩存中插入數據
- 導致再次查詢時,從一級緩存中讀取數據時,讀取的數據是緩存中的臟數據
處理方法
不在循環中調用查詢
開啟查詢語句的一級緩存刷新機制
設置statement配置中的flushCache=‘true’ 屬性,默認情況下為true即刷新緩存,如果改成false則不會刷新。使用緩存時如果手動修改數據庫表中的查詢數據會出現臟讀。
注意點
一級緩存修改的問題不限於循環中,在統一事務中重復查詢也會出現類似問題
mybatis一級緩存
1、一級緩存的生命周期有多長?
MyBatis在開啟一個數據庫會話時,會 創建一個新的SqlSession對象,SqlSession對象中會有一個新的Executor對象。Executor對象中持有一個新的PerpetualCache對象;當會話結束時,SqlSession對象及其內部的Executor對象還有PerpetualCache對象也一並釋放掉。
如果SqlSession調用了close()方法,會釋放掉一級緩存PerpetualCache對象,一級緩存將不可用。
如果SqlSession調用了clearCache(),會清空PerpetualCache對象中的數據,但是該對象仍可使用。
SqlSession中執行了任何一個update操作(update()、delete()、insert()) ,都會清空PerpetualCache對象的數據,但是該對象可以繼續使用