故障排除 Mybatis ORA-01000 和 本地缓存问题

※异常信息  环境 MyBatis Oracle11.2c Terasoluna Batch
Caused by: org.springframework.jdbc.UncategorizedSQLException:
### Error updating database. Cause: java.sql.SQLException: ORA-00604: 再帰SQLレベル1でエラーが発生しました。
ORA-01000: 最大オープン?カーソル数を超えました。
ORA-00604: 再帰SQLレベル1でエラーが発生しました。
ORA-01000: 最大オープン?カーソル数を超えました。

※调试
cmd
sqlplus
sys as sysdba
$password

##第一条sql 显示现在使用中的cursor数 和 最大允许cursor数
##第二条sql 显示现在使用中的cursor 的用户 sid sql文内容
##spool logFile; xxxx ; spool off;
spool C:\Users\nttdata\Desktop\sqlseq.txt;
select max(a.value) as highest_open_cur, p.value as max_open_cur
from v$sesstat a, v$statname b, v$parameter p
where a.statistic# = b.statistic#
and b.name = ‘opened cursors current‘
and p.name= ‘open_cursors‘
group by p.value;

select c.user_name, c.sid, sql.sql_text
from v$open_cursor c, v$sql sql
where c.sql_id=sql.sql_id;
spool off;

※原因
最后发现是在sqlmap中使用了 ${constant},
而值是每次取到sequence的nextVal然后拼接xml配置文件中的固定值,所以都不相同。
$是直接拼入sql语句中的内容。一般使用#{value}。
当每次都不同时,生成的statement就不同。
在sqlsession关闭前,这样的statement超过最大值就会报 ORA-01000

※解决
将不变的内容用${constant}拼接,变化的内容用#{value}
这样#{value}在statement中是一个?,每次执行的都一样,不会新加statement。问题解决。

-------------------------------------------------------------------------------------
※异常
同时在调查这个问题的时候发现了另一个隐藏的问题
select sequenceName.nextval from dual
但将结果写入文件时,值除了第一条记录并没有采番。
当将结果插入db时,每次值都是新的。
查看log发现写文件的情况下,sql并未执行。

修改前
[2017/09/07 18:36:51] [main] [j.c.n.d.e.b.MappingBLogic] [DEBUG] read record [data={aaa=576}]
[2017/09/07 18:36:51] [main] [j.c.n.d.o.h.UnifiedCodeConvertHandler] [DEBUG] unified code convert execute [recordNo=576, column=aaa, value=576]
[2017/09/07 18:36:51] [main] [j.c.n.d.o.h.UnifiedCodeConvertHandler] [DEBUG] unified code convert success [recordNo=576, srcName=aaa, srcValue=576, destName=newseq, destValue=4209, replace=false]

修改后 第一条以后的数据,多了sql执行的参数和结果
[2017/09/07 18:37:24] [main] [j.c.n.d.e.b.MappingBLogic] [DEBUG] read record [data={aaa=622}]
[2017/09/07 18:37:24] [main] [j.c.n.d.o.h.UnifiedCodeConvertHandler] [DEBUG] unified code convert execute [recordNo=622, column=aaa, value=622]
[2017/09/07 18:37:24] [main] [j.c.n.d.e.d.Q.select ] [DEBUG] ==> Parameters: abcd(String)
[2017/09/07 18:37:24] [main] [j.c.n.d.e.d.Q.select ] [DEBUG] <== Total: 0
[2017/09/07 18:37:24] [main] [j.c.n.d.e.d.Q.select ] [DEBUG] ==> Parameters:
[2017/09/07 18:37:24] [main] [j.c.n.d.e.d.Q.select ] [DEBUG] <== Total: 1
[2017/09/07 18:37:24] [main] [j.c.n.d.o.h.UnifiedCodeConvertHandler] [DEBUG] unified code convert success [recordNo=622, srcName=aaa, srcValue=622, destName=newseq, destValue=4831, replace=false]

※原因
http://www.mybatis.org/mybatis-3/zh/java-api.html

清理 Session 级的缓存
void clearCache()
SqlSession 实例有一个本地缓存在执行 update,commit,rollback 和 close 时被清理。要 明确地关闭它(获取打算做更多的工作) ,你可以调用 clearCache()。

http://www.mybatis.org/mybatis-3/java-api.html
中文只说一句话,因为解释很清楚,还是要看英文~~~
本地缓存
Mybatis使用两种缓存,本地缓存和二级缓存。
每当创建一个新的session,Mybatis会创建一个本地缓存并将它绑定到这个session。
在这个session中执行的任何查询会被缓存到本地缓存中,所以当后面使用相同的查询语句和参数时,不会去查询DB。
本地缓存在update,commit,rollback和close时被清空。
本地缓存默认在整个session生存周期中使用。本地缓存是用来解决循环引用和加快嵌套查询,所以他不能被完全禁用。
但是你可以设置本地缓存只在语句执行中使用,localCacheScope=STATEMENT.
mybatis-config.xml
<configuration>
<settings>
<setting name="localCacheScope" value="STATEMENT" />
</settings>
</configuration>

注意当localCacheScope被设置为SESSION时,Mybatis会返回缓存中的对象引用。对返回值比如list的修改都会影响本地缓存中的值
并影响session生命周期中从缓存中返回的值。所以,最佳实践是不要修改Mybatis的返回值。

你也可以手动清空本地缓存,用sqlSession的下面方法。
void clearCache()

Local Cache

MyBatis uses two caches: a local cache and a second level cache.

Each time a new session is created MyBatis creates a local cache and attaches it to the session. Any query executed within the session will be stored in the local cache so further executions of the same query with the same input parameters will not hit the database. The local cache is cleared upon update, commit, rollback and close.

By default local cache data is used for the whole session duration. This cache is needed to resolve circular references and to speed up repeated nested queries, so it can never be completely disabled but you can configure the local cache to be used just for the duration of an statement execution by setting localCacheScope=STATEMENT.

Note that when the localCacheScope is set to SESSION, MyBatis returns references to the same objects which are stored in the local cache. Any modification of returned object (lists etc.) influences the local cache contents and subsequently the values which are returned from the cache in the lifetime of the session. Therefore, as best practice, do not to modify the objects returned by MyBatis.

You can clear the local cache at any time calling:

void clearCache()

※解决
没有去改配置。
我使用了手动清空的方法。
注入一个sqlSession
当要取sequence的时候,先清空缓存。
private SqlSession sqlSession;
sqlSession.clearCache();

实验了下配置为STATEMENT效果相同

时间: 2024-10-27 01:46:35

故障排除 Mybatis ORA-01000 和 本地缓存问题的相关文章

细化如何安装LNMP + Zabbix 监控安装文档以及故障排除

1.LNMP所需安装包: 上传如下软件包到/soft目录中 mysql- 5.1.71(centos6.5 64位自带)也可根据版本自行挑选,前提你了解这个版本 pcre-8.36.tar.gz nginx-1.6.2.tar.gz jpegsrc.v9a.tar.gz libmcrypt-2.5.8.tar.gz php-5.6.3.tar.gz 2.配置系统YUM源 cd /etc/yum.repos.d/ vim install.repo [LOCALYUMSOURCE] name=PD3

DNS服务器的维护与故障排除

1. DNS故障诊断的常用工具或命令 诊断DNS解析故障的四个常用命令工具: ①unbound-checkconf:用于检查unbound服务器配置文件的语法错误 ②unbound-control:是一个用于控制远程Unbound服务器的工具. ③nscd(name service cache daemon,名称服务缓存管理器):一种专门对DNS缓存进行管理的工具(RHEL7中默认未安装,可使用yum -y install nscd命令安装). ④dig(Domain Information G

Atitit.故障排除系列---NoClassDefFoundError NoClassDefFoundError

Atitit.故障排除系列---NoClassDefFoundError  NoClassDefFoundError java.lang.ClassNotFoundException找不到类异常.当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常. 还有个NoClassDefFoundError,,是classload 新不上class加载.. 查看class是存在的... 作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:[

Linux -- 常见故障排除

目前Linux的擅长应用领域是:单一应用的基础服务器应用,譬如DNS.Web服务器.NFS服务器.防火墙.文件服务器.代理服务器.中小型数据库.Linux网络故障大多与服务器配置有关.下面我们介绍一下故障排除步骤. 一. Linux网络故障之网卡故障 Linux的网络实现是模仿FreeBSD的,它支持FreeBSD的带有扩展的Sockets(套接字)和TCP/IP协议.它支持两个主机间的网络连接和Sockets通讯模型,实现了两种类型的Sockets:BSD Sockets和INET Socke

Atitit.故障排除系列---NoClassDefFoundError&#160;&#160;NoClassDefFoundError&#160;ClassNotFoundException

Atitit.故障排除系列---NoClassDefFoundError  NoClassDefFoundError ClassNotFoundException 1. java.lang.ClassNotFoundException找不到类异常.当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常.1 2. 查看class是存在的...1 3. 把eclipse这个class  添加磊个sysoout  ,,,叫哪重新编译给挂....三

MyBatis学习---------调用存储过程和缓存

一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 1 create table p_user( 2 id int primary key auto_increment, 3 name varchar(10), 4 sex char(2) 5 ); 6 7 insert into p_user(name,sex) values('A',"男"); 8 insert into p_user(name,sex) values('B',&qu

利用Ring Buffer在SQL Server 2008中进行连接故障排除

原文:利用Ring Buffer在SQL Server 2008中进行连接故障排除 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/11/21/ring-buffer-sql-server-2008.aspx SQL Server 2008中包含一个新功能,旨在帮助解决特别棘手的连接问题.这个新功能是Connectivity Ring Buffer,它可以捕捉每一个由服务器发起的连接关闭记录(server-initiated connection

OpenStack服务启动故障排除经验

今天同事在配置OpenStack的计算节点(在CentOS 7上部署)时遇到一个问题,发现在控制节点上运行nova service-list发现只有4行,没有nova-compute service,让我帮他排查. 提前透露原因:这位同事在/etc/nova/nova.conf配置文件中verbose = True 写成了 verbose =Ture,我也是检查了半天(两眼对了3遍)没看出来,有点汗! 根据我以前掌握的经验,OpenStack的部署过程遇到的问题可归纳总结为配置文件问题.配置步骤

Java性能故障排除工具

Java性能故障排除工具: 1.jconsole是随着JDK 1.5而推出的.这是一个Java监测和管理控制台-JMX兼容的图形工具来监测Java虚拟机.它能够同时监测本地和远程的JVMs.详情可查看:jconsole工具介绍 2.VisualVM 集成了几个现有的JDK软件工具,轻量级内存和CPU信息概要能力.这个工具被设计为同时在生产和开发时使用,进一步提高监视的能力和Java SE平台的性能分析能力. 3.HeapAnalyzer 能够通过它采用启发式搜索引擎和分析Java堆栈存储信息发现