我正在使用mybatis连接到Oracle。
我的mybatis配置是:
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
<setting name="logImpl" value="${logImpl}" />
<setting name="defaultStatementTimeout" value="10" />
</settings>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="poolPingConnectionsNotUsedFor" value="290000"/>
<property name="poolPingQuery" value="SELECT COUNT(*) FROM RESORT"/>
<property name="poolPingEnabled" value="true"/>
</dataSource>
</environment>
</environments>
我的开放会话代码就像
SqlSession sqlSession = factory.openSession();
Object result = null;
try
{
QueryInfoMapper mapper = sqlSession.getMapper(QueryInfoMapper.class);
result = mapper.queryInfoFromOpera(mybatisMapping);
} finally
{
sqlSession.close();
}
由于类的应用范围,而sqlSession不能在应用范围内使用,所以我必须自己管理sqlSession。
2019-04-11 15:30:41,861信息[stdout](默认任务-57)声称连接过期962608913。
2019-04-11 15:30:41,861信息[stdout](默认任务-57)从池返回了一个错误的连接(962608913),正在获取另一个连接。
2019-04-11 15:30:41,895信息[stdout](默认任务-57)创建连接1812494479。
2019-04-11 15:30:41,895信息[stdout](默认任务-57)将JDBC连接上的自动提交设置为false[oracle.JDBC.driver.t4cconnection@6c08788f]
2019-04-11 15:30:41,895 INFO[stdout](默认任务-57)==>准备:从(从opera.name_reservation中选择TRAVEL_AGENT_NAME,其中RESV_NAME_ID=?)中选择行Num=1
2019-04-11 15:30:41,896 INFO[stdout](默认任务-57)==>参数:288541(字符串)
2019-04-11 15:30:41,900信息[stdout](默认任务-57)<==列:TRAVEL_AGENT_NAME
2019-04-11 15:30:41,900信息[stdout](默认任务-57)<==row:null
2019-04-11 15:30:41,900信息[stdout](默认任务-57)<==总计:1
2019-04-11 15:30:41,900信息[stdout](默认任务-57)将JDBC连接上的自动提交重置为true[oracle.JDBC.driver.t4cconnection@6c08788f]
2019-04-11 15:30:41,900信息[stdout](默认任务-57)正在关闭JDBC连接[oracle.JDBC.driver.t4cConnection@6c08788f]
2019-04-11 15:31:00,788信息[stdout](默认任务-60)声称连接过期1228464923。
2019-04-11 15:31:00,788 INFO[stdout](默认任务-60)从池返回了一个错误的连接(1228464923),正在获取另一个连接。
2019-04-11 15:31:00,820 INFO[stdout](默认任务-60)创建连接265625885。
2019-04-11 15:31:00,820信息[stdout](默认任务-60)在JDBC连接[oracle.JDBC.driver.t4cconnection@FD5211d]上设置自动提交为false
2019-04-11 15:31:00,820 INFO[stdout](默认任务-57)返回连接1812494479到池。
看到日志,根据时间戳,它似乎发生在关闭连接(这里是事务)的过程中
关闭连接/事务失败的原因是什么?如何避免关闭连接/事务失败?
=================================================
更新:我又遇到了这个问题,日志来了一些不同的东西:
2019-04-13 15:42:35,493 INFO[stdout](默认任务-62)从池返回了一个错误的连接(1963609369),正在获取另一个连接。
2019-04-13 15:42:35,493 INFO[stdout](默认任务-62)从池签出连接195963529。
2019-04-13 15:42:35,493信息[stdout](默认任务-62)测试连接195963529....
2019-04-13 15:42:54,448 INFO[stdout](默认任务-62)执行ping查询“Select COUNT(*)FROM Resort”失败:IO错误:套接字读取超时
2019-04-13 15:42:54,448 INFO[stdout](默认任务-62)连接195963529错误:IO错误:套接字读取超时
2019-04-13 15:42:54,448 INFO[stdout](默认任务-62)从池返回了一个错误的连接(195963529),正在获取另一个连接。
顺便说一句,我将ping sql更改为select 1 FROM dual
。什么可能导致此套接字读取超时?
这里我可以看出几个问题:
您肯定需要使用select 1 FROM dual
作为ping查询。否则,你会在每个打开的连接上做一些不那么便宜的操作。
在发生此问题时检查oracle是否健康是有意义的。它是否回应当时的其他质疑?CPU/IO/内存/交换的使用情况如何,等等。如果服务器负载很高,可能是它没有及时响应。
检查网络连接问题是一个非常广泛的主题。我知道的最可靠(也是最复杂)的方法是在两端捕获网络流量(使用tcpdump或WireShark这样的工具)并对它们进行比较。
那么mybatis连接池出现了问题。
这意味着,如果应用程序尝试打开新连接,并且所有连接都很忙,那么mybatis将关闭最旧的连接,如果该连接在使用中超过20秒(默认情况下)。
如果您有一些长时间运行的查询,它本身可能是一种非常意外的行为。另一个可能也是更大的问题是这是如何在Mybatis中实现的。为了获取连接,回滚事务的请求是从请求新连接的线程执行的(在上面的示例中,threadDefault Task-57
保留了连接,而threadDefault Task-60
试图从池中获取连接)。
这就是问题所在,因为oracle jdbc驱动程序在从多个线程访问连接时需要正确的同步,而mybatis不这样做:
对连接的受控串行访问(例如由连接缓存提供的访问)既是必要的,也是鼓励的。但是,Oracle强烈反对在多个线程之间共享数据库连接。避免允许多个线程同时访问一个连接。如果多个线程必须共享一个连接,请使用规范的Begin-using/End-using协议。
因此,无法同步多个线程对共享资源(连接)的访问可能会导致各种一致性问题,我不排除关闭连接的问题是由于缺少同步而导致的连接在较早时进入了某种不一致状态的可能性。
由于池耗尽时的情况不会发生(或发生的频率较低),因此增加池大小可为给定负载消除此问题。
注意,并发问题很难重现,肯定的合成测试几乎不能保证。这是一个广泛的主题,所以建议您看Goetz的书,以获得详细信息。
我将更改连接池实现,即使用https://github.com/swaldman/c3p0或https://commons.apache.org/proper/commons-dbcp/或https://brettwooldridge.github.io/hikaricp/。
我使用weblogic应用服务器和oracle数据库。我使用jdbc与oracle数据库通信。我从weblogic数据源获得连接,并向表中插入一条记录。问题是,当我想关闭连接(插入数据库后)时,我会遇到一个异常(连接已经关闭)。这是我的代码: 但是联系。close语句引发异常: 我试图避免连接。close语句(因为我教过连接是自动关闭的!!但过了一段时间,所有的连接都打开了,因此引发了一个异常)
问题内容: 我一直在对我们的一个宠物项目进行代码审查(通常使用诸如FindBugs之类的工具),并且FindBugs将以下代码标记为错误的(伪代码): 错误是此代码可能不会释放资源。我发现ResultSet和Statement没有关闭,所以我最终将它们关闭: 但是我在许多项目(来自许多公司)中遇到了上述模式,没有人关闭ResultSets或Statements。 关闭连接时,是否关闭了Result
每个人我需要使用服务器和客户端证书连接到服务器。我正在使用以下代码:(移植形式的android) 我已为ssl和握手启用调试属性,并获得以下输出: 我得到这个错误在Android设备和桌面java。但是我可以使用这个客户端证书自由地用网络浏览器连接到服务器。 也许这是重要的或不Url的服务器是:https://icon.sbrf.ru:9443(注意端口)也客户端证书是与西里尔名称(我不知道是这件
问题内容: 我想使用OkHttpClient加载URL,如果给定URL的网站以pdf内容类型响应,我将继续下载PDF,否则我想忽略响应。 我的问题是,我是否需要做一些特殊的事情来关闭请求/响应,或者如果我选择不读取响应字节流,是否需要做任何事情来表明我将不使用响应?如果没有,OkHttpClient何时关闭连接? 问题答案: 调用将释放响应所拥有的所有资源。连接池将使连接保持打开状态,但是如果未使
关闭连接标志着服务器和客户端之间的通信结束。使用事件可以关闭连接,标记通信结束后,服务器和客户端之间无法进一步传输消息。由于连接不良,也可能发生事件。 方法代表再见握手。它终止连接,除非连接再次打开,否则不能交换任何数据。 与前面的示例类似,当用户单击第二个按钮时,调用方法。 也可以传递前面提到的代码和原因说明参数,如下所示。 以下代码完整概述了如何关闭或断开Web Socket连接 - 在浏览器
给出错误的方法如下: 如何创建一个没有泄漏的连接?为什么Hikari认为我的conn.close()方法没有关闭连接?任何想法都很欣赏。