mybatis多線程插入數據時出現的問題


最近在mybatis多線程插入數據時出現兩則問題,記錄如下:

問題1:我的邏輯如下

1 select表中category_name字段,如果有的話則取出其ID

2 如果木有的話則插入一條數據,同時用last_insert_id()函數將主鍵主增長ID找出

mybatis配置如下

<insert id="insertCommonCategory" parameterType="CommonCategory">
        insert ignore into common_category (category_name,category_group)
        values(#{categoryName},#{categoryGroup})
<!-- 多線程環境中會導致insert失敗,導致該段邏輯有誤
        <selectKey keyProperty="id" resultType="java.lang.Integer">
            select last_insert_id() as id
        </selectKey>
-->
</insert>
<select id="selectIdbyCategoryNameAndGroup" parameterType="CommonCategory" resultType="java.lang.Integer">
        select id from common_category where category_name=#{categoryName} and category_group=#{categoryGroup}
</select>
 

由於在多線程環境中,可能會導致邏輯同時進入2邏輯,此時會導致insert失敗,last_insert_id()函數返回一個錯誤的id

問題2:根據以上現象,我的更改為

1 在insert加上ignore修飾,可讓insert失敗時不報錯,但last_insert_id()函數依然有錯,所以不用它

2 將邏輯改成 (1) 查找category_name字段,有的時候取出其ID,(2)木有的話新插入一條,insert語句加上ignore修飾,(3)重新進行(1)步驟

但此時依然報錯,說是(3)步驟依然找不到ID,翻閱相關資料找到的原因為:Mysql的事務隔離級別為可重讀, 即在同一個事務中始終看到相同的數據,此時錯誤發生的原因為,在進行(2)步驟時,insert失敗,(3)步驟依然就查不到數據了,解決辦法有二

1 更改mysql事務隔離級別Read Commited或更低級別

2 利用mybatis的cache,在mapper的配置文件中加上<cache/>標簽,然后insert標簽上flushCache屬性設置為true,使其在多線程環境中能隨時的刷新cache

看來多線程編程有很多難以預料的問題

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM