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