當前位置:
首頁 >
mybatis/mybatis plus lambda会话缓存失效(1)
發布時間:2024/3/13
48
豆豆
生活随笔
收集整理的這篇文章主要介紹了
mybatis/mybatis plus lambda会话缓存失效(1)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
場景
有個業務比較長的接口,會對某張模板表做反復查詢,接口執行時間比較長有1-2秒,需要優化,查看后臺日志,同樣的查詢sql在反復執行。而且都是lambda的getById接口,所以初步朝lambda不支持緩存方向排查(結果不是)
排查思路
從getById起看源碼鏈路,最終找到緩存的關鍵源碼在BaseExecutor里
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());if (closed) {throw new ExecutorException("Executor was closed.");}if (queryStack == 0 && ms.isFlushCacheRequired()) {clearLocalCache();}List<E> list;try {queryStack++;list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; // 1 主要取緩存的邏輯在這里,key是一個很長的字符串拼接,和參數值、mapperId、sql、beanId有關if (list != null) {handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}if (queryStack == 0) {for (DeferredLoad deferredLoad : deferredLoads) {deferredLoad.load();}// issue #601deferredLoads.clear();if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {// issue #482clearLocalCache();}}return list;} private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {List<E> list;localCache.putObject(key, EXECUTION_PLACEHOLDER);try {list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);} finally {localCache.removeObject(key);}localCache.putObject(key, list); // 2 每次執行后會把值放到緩存里if (ms.getStatementType() == StatementType.CALLABLE) {localOutputParameterCache.putObject(key, parameter);}return list;}通過給1的地方打斷點發現,每隔一段時間cache的size會變成0,估計是被清空了,給cache的clear打了個斷點,進去后看了下調用堆棧,清空邏輯在
public int update(MappedStatement ms, Object parameter) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());if (closed) {throw new ExecutorException("Executor was closed.");}clearLocalCache();return doUpdate(ms, parameter);}這里沒有指定key,是全部清空,所以即使更新的是A表數據,B表也會清空。
解決方案
解決方案計劃有兩個
1 寫一個類似spring cache的功能在service層做會話級緩存(微服務場景,全局緩存不行)
2 重新baseExecutor的query方法,在mybatis層面上加標簽注明表,只刷新同表數據
總結
以上是生活随笔為你收集整理的mybatis/mybatis plus lambda会话缓存失效(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel学习日记:L19-定义名称In
- 下一篇: jquery animate 数字动态变