MyBatis/MyBatis-Plus同事務循環(huán)調(diào)用存儲過程獲取主鍵重復問題分析及解決
問題
mybatis有如下代碼獲取序列作為主鍵
IdMapper.java
@Select("SELECT TABLE.NEXTVAL FROM DUAL")
String getId();
同一事務循環(huán)調(diào)用查詢偽代碼
@Transactional(rollbackFor = Exception.class)
public QueryMedicalFeeRes queryMedicalFee(QueryMedicalFeeReq req) {
for (Obj o : objs) {
Long id = idMapper.getId();
log.info("id{}",id);
}
}
輸出如下:id都是1
id1
id1
id1
id1
原因
因為MyBatis的一級緩存導致的。而且MyBatis默認開啟一級緩存,這樣就會導致循環(huán)調(diào)用查詢方法的時候,直接從緩存獲取,不會查詢數(shù)據(jù)庫,從而獲取到的數(shù)據(jù)都是緩存數(shù)據(jù)。
但請注意,并不是所有查詢都不使用一級緩存!而是當你需要查詢的內(nèi)容是需要變化的時候才要禁用一級緩存。如:查詢Oracle的序列、查詢存儲過程獲取主鍵值等情況才需要禁用一級緩存。
解決辦法
禁用一級緩存
<select id="getId" resultType="java.lang.Long" useCache="false" flushCache="true">
SELECT TABLE.NEXTVAL AS ID FROM DUAL
</select>
@Select("SELECT TABLE.NEXTVAL FROM DUAL")
@Options(useCache = false, flushCache = Options.FlushCachePolicy.TRUE)
String getId();
如果是存儲過程
<select id="getId" resultType="java.lang.Long" statementType="CALLABLE" useCache="false" flushCache="true">
{call GET_NEXT_ID(#{identity,mode=IN,jdbcType=VARCHAR},#{tableName,mode=IN,jdbcType=VARCHAR},#{count,mode=IN,jdbcType=INTEGER},#{currentNo,mode=OUT,jdbcType=INTEGER})}
</select>
```java
@Select("{call GET_NEXT_ID(#{identity,mode=IN,jdbcType=VARCHAR},#{tableName,mode=IN,jdbcType=VARCHAR},#{count,mode=IN,jdbcType=INTEGER},#{currentNo,mode=OUT,jdbcType=INTEGER})}")
@Options(statementType = StatementType.CALLABLE, useCache = false, flushCache = Options.FlushCachePolicy.TRUE)
String getId();
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot處理JSON數(shù)據(jù)方法詳解
這篇文章主要介紹了SpringBoot整合Web開發(fā)中Json數(shù)據(jù)處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-10-10
Spring監(jiān)聽器及定時任務實現(xiàn)方法詳解
這篇文章主要介紹了Spring監(jiān)聽器及定時任務實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
SpringMVC框架post提交數(shù)據(jù)庫出現(xiàn)亂碼解決方案
這篇文章主要介紹了SpringMVC框架post提交數(shù)據(jù)庫出現(xiàn)亂碼解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09
Mybatis中where標簽與if標簽結(jié)合使用詳細說明
mybatis中if和where用于動態(tài)sql的條件拼接,在查詢語句中如果缺失某個條件,通過if和where標簽可以動態(tài)的改變查詢條件,下面這篇文章主要給大家介紹了關(guān)于Mybatis中where標簽與if標簽結(jié)合使用的詳細說明,需要的朋友可以參考下2023-03-03
Spring Data JPA 關(guān)鍵字Exists的用法說明
這篇文章主要介紹了Spring Data JPA 關(guān)鍵字Exists的用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06

