最近项目出现个问题,就是tomcat跑一段时间就会假死,页面能打开但是无法登陆,经过定位发现是数据库连接池满了,因为我之前hibernate用得不多,所以就写了几个测试代码来验证下哪种情况导致的。数据库持久层用的hibernate,所以只有执行原生sql和存储过程时会手动获取连接,那么问题应该就是出现在这些地方,但是之前没有出现问题,为什么现在出问题了呢?还是先写验证测试先,项目获取数据库连接获取用了三种:
①、
ConnectionProvider cp = ((SessionFactoryImplementor) this.getSessionFactory()).getConnectionProvider(); Connection conn = cp.getConnection();
②、
Session session = this.getSessionFactory().openSession(); Connection conn = session.connection();
③、
Session session = this.getSessionFactory().getCurrentSession(); Connection conn = session.connection();
经过测试发现:
①这种方式获得数据库连接后,如果不手动关闭则会一直占用,必须调用conn.close()或者cp.closeConnection(conn)手动释放数据库连接。
②这种方式获得的数据库连接,也必须要手动关闭,否则也是会一直占用,但是关闭数据库连接不是conn.close()而是session.close()
③这种方式获得的数据库连接,可以不需要手动关闭,在程序执行完成之后会自动释放数据库连接
之前跑得正常的程序为什么这几天出现为问题了呢,然后看了一下最近的svn提交版本,发现打开了一个定时器,每天调用存储过程一次,这里却未关闭数据库连接。立马修正,测试,搞掂。
后来想想之前就好好的 为啥这里会有问题呢?对比了下代码原来这里用得是openSession而其他地方用的是getCurrentSession,然后google了下getCurrentSession和openSession的区别发现:
1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。
怪不得之前不会占满数据库连接池,原来是用得是getCurrentSession,即使不手动关闭也没关系。
又长点知识,特此mark一下。
相关推荐
Native SQL查询允许我们直接使用SQL语句来与数据库交互,不受HQL的限制,可以充分利用SQL的功能,如存储过程、自定义函数、复杂的联接和子查询等。这种方式尤其适用于那些对数据库性能有极高要求或者对数据库结构有...
在Hibernate中,调用存储过程通常通过Session对象的createNativeQuery()方法实现,这个方法用于创建原生SQL查询,可以方便地调用数据库的自定义SQL或者存储过程。以下是一个简单的示例,展示了如何调用一个不带参数...
例如,使用`org.hibernate.boot.model.naming.PhysicalNamingStrategy`接口来自定义表名生成策略,或者利用`Session.createSQLQuery()`方法直接执行原生SQL。 2. **多数据库支持**:为了适应不同的数据库,如MySQL...
在此基础上,Hibernate OGM框架可以自动地将JAVA对象解析成适合存储在NoSQL数据库中的格式,例如HBase中的点分格式,而对于SQL数据库则通过封装原生API写入数据库引擎。这种方式为混合使用HBase和MySQL这类SQL数据库...
4. **定义Hibernate Native SQL查询**:由于Hibernate默认不支持调用存储过程或函数,我们需要使用`@NamedNativeQuery`或`@SqlResultSetMapping`注解来定义一个原生SQL查询,用于调用Oracle函数。例如: ```java @...
开发者会使用Hibernate与SQL2000进行交互,通过HQL(Hibernate Query Language)或原生的SQL语句来执行查询、插入、更新和删除操作。 **项目结构与实现** 这个项目可能包含以下几个主要部分: 1. 用户界面:使用...
NSQL指的是原生SQL语句,即直接使用的SQL语句。在Hibernate中,可以通过`createSQLQuery()`方法来执行NSQL语句。这种方式适用于那些无法通过HQL表达的复杂查询或者需要与特定数据库特性紧密结合的情况。 **示例代码...
- 创建一个`SQLQuery`对象,该对象允许执行原生SQL查询。 - 设置参数值。 - 执行存储过程。 ```java SQLQuery sqlQuery = session.createSQLQuery("{call 漤(?)}"); sqlQuery.setString(0, "String"); sql...
执行SQLQuery对象的executeUpdate或list方法来执行存储过程。对于无返回结果或只有输出参数的情况,通常使用executeUpdate。 ```java int rowsAffected = query.executeUpdate(); ``` 5. **关闭资源** 最后,...
- **SQL查询**:除了使用HQL(Hibernate Query Language)和Criteria API,还可以使用原生SQL进行复杂查询。 - **缓存机制**:一级缓存是SessionFactory级别的,二级缓存可以是共享的,可以提高性能但需要正确配置...
对于复杂的查询需求,还可以使用原生SQL,通过Session的createSQLQuery()方法执行。 进一步,Hibernate的缓存机制提高了性能。一级缓存是Session级别的,所有在Session内的操作都先在内存中完成。二级缓存则可配置...
在Hibernate中执行原生SQL查询时,可以通过`addScalar`方法指定返回值的类型,从而改变Hibernate对char类型字段的处理方式。具体操作如下: ```java Session session = this.getSession(); SQLQuery query = ...
比如,刚开始学习Java的时候可能会遇到JDBC,它是连接Java和数据库的桥梁,我们可以使用JDBC来建立与数据库之间的连接并且执行相应的SQL语句。虽然JDBC的执行效率很高,但是其开发效率比较低。正是如此,市面上出现...
在IT领域,尤其是在Java...通过使用`flush()`和`evict()`、执行原生SQL语句或使用存储过程,可以显著提升数据库操作的效率,同时减少服务器资源的消耗。开发者应根据具体的应用场景和数据库特性选择最合适的优化方案。
- **HQL和Criteria API**:学习如何构建面向对象的查询,以及它们与原生SQL的区别。 - **缓存机制**:掌握一级缓存(Session级别的内存缓存)和二级缓存(SessionFactory级别的分布式缓存)的工作原理。 - **事务...
至于原生SQL语句的使用,虽然Hibernate提供了一套强大的ORM机制,但在某些特定场景下,如复杂的数据库操作或性能优化,可能需要直接使用SQL。在Hibernate中,可以通过以下方式使用原生SQL: - `Session....
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...
2. **使用原生SQL或存储过程**:直接使用JDBC API执行原生SQL或调用存储过程,绕过Hibernate的ORM层,可以实现更高性能的批量操作。例如,可以创建一个存储过程用于批量更新操作: ```sql CREATE OR REPLACE ...
本文将详细介绍使用Java调用存储过程的三种方法:通过Hibernate框架、使用JDBC原生方式以及结合Hibernate的SQLQuery接口。 #### 一、通过Hibernate框架调用存储过程 Hibernate是一个非常流行的Java持久化框架,它...
MyBatis提供了一个XML或注解配置的机制,用于定义SQL语句、存储过程以及参数映射。 至于HSQL,这是一个轻量级的、纯Java的SQL数据库引擎,常用于测试和嵌入式应用。它的优点在于快速启动,内存模式下运行无需额外...