当前位置: 代码网 > it编程>编程语言>Java > MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

2025年09月24日 Java 我要评论
问题mybatis有如下代码获取序列作为主键idmapper.java @select("select table.nextval from dual") string getid();同

问题

mybatis有如下代码获取序列作为主键

idmapper.java

    @select("select table.nextval from dual")
    string getid();

同一事务循环调用查询伪代码

	@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默认开启一级缓存,这样就会导致循环调用查询方法的时候,直接从缓存获取,不会查询数据库,从而获取到的数据都是缓存数据。

但请注意,并不是所有查询都不使用一级缓存!而是当你需要查询的内容是需要变化的时候才要禁用一级缓存。如:查询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();

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com