Mybatis整合二級快取與同時使用快取與事務存在的坑

Jack2k發表於2021-09-09

今天在看分散式事務的時候,突然收到app不能簽到的訊息,趕緊解決。

具體解決方法:
1、把執行錯誤的處理方法提取出來,作為測試方法
2、這個方法裡面有兩個插入語句,一條查詢語句,一個更新語句,涉及到三張表。
3、報錯資訊為

"nested exception is org.apache.ibatis.exceptions.PersistenceException: n### Error committing transaction.  Cause: java.lang.NullPointerException: Can't serialize nulln### Cause: java.lang.NullPointerException: Can't serialize null

4、今天只是為了做叢集,將Mybatis的快取由預設的記憶體快取改為了Memcached,突然就報這個錯。

思路

  • 插入語句一般不會快取,只有Select語句才會快取。不能持久化,我只用了一個選擇語句,這個語句是執行正常的啊,檢視日誌,發現問題。

 Flushing keys: [_mybatis_22a025828e62efbe0adda93d10f748e15fe8cecd]

 Flushing group: _mybatis_2610d3ffc622c90f08b859a4e787189c9230d66e

  • 每次插入或更新語句的時候都會Flush cache,導致剛查詢的快取結果為清空,因為加了事務註解,所以等方法執行完畢的時候,快取為null,然後報錯。

教訓

在事務處理的時候,如果是使用Memcache做快取,儘量不要把Select語句和Insert語句放到一起。
如果是使用Redis作為Mybatis的快取,則未發現問題。

額外

Mybatis二級快取的擴充套件包中檔案數量較少,並且官方的Mybatis-Redis直接使用,當前版本也會報錯,無法整合。
解決方案:

  1. 將所有Mybatis-redis擴充套件包複製到當前專案

 


二級快取包中檔案

  1. 修改Rediscache的構建方法

public RedisCache(final String id) {
    if (id == null) {
      throw new IllegalArgumentException("Cache instances require an ID");
    }
    this.id = id;
    RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();
    pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(),
            redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(),
            redisConfig.getDatabase(), redisConfig.getClientName(),false,null,null,null);
  }
  1. 可以使用Redis作為Mybatis的二級快取,在Mybatis全域性配置與Mapper檔案中配置好即可。

整合Mybatis-Memecache也類似,可以複製二級快取包內容,進行擴充套件

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/36/viewspace-2817186/,如需轉載,請註明出處,否則將追究法律責任。

相關文章