Spring3+Hibernate3 保持数据库连接不释放问题

2020/03/19 22:19
阅读数 937

老项目用的元数据封装框架,没有设置hibernate连接释放模式。

https://www.oschina.net/uploads/doc/hibernate-3.2/org/hibernate/ConnectionReleaseMode.html

首先hibernate的Connection release mode有以下几种:
1 after_statement 2 after_transaction 3 on_close 其中after_statement 用在jta中 ,on_close 是3.1之前遗留的(也许是为spring留的-_-),也就是3.1之前默认是on_close ,但3.1之后默认如果单独使用hibernate是after_transaction,如果有第三方事务管理,就用第三方提供的默认值,spring默认使用了on_close。
在spring管理事务中我们看看系统启动后默认使用的配置:
1,ransaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory使用spring事务策略
2,hibernate内部 Automatic session close at end of transaction: disabled 因为已经交给spring了
3   Connection release mode: auto 默认,也就是没有配置hibernate.connection.release_mode的时候,但是这里有地方需要注意:也就是前面提到的使用第三方策略时的问题:看一下代码:

String releaseModeName  =  PropertiesHelper.getString( Environment.RELEASE_CONNECTIONS, properties,  " auto "  );
        log.info( 
" Connection release mode:  "   +  releaseModeName );
        ConnectionReleaseMode releaseMode;
        
if  (  " auto " .equals(releaseModeName) )  {
            
releaseMode = transactionFactory.getDefaultReleaseMode();        }

         else   {
            releaseMode 
= ConnectionReleaseMode.parse( releaseModeName );
            
if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT && !connections.supportsAggressiveRelease() ) {
                log.warn( 
"Overriding release mode as connection provider does not support 'after_statement'" );
                releaseMode 
= ConnectionReleaseMode.AFTER_TRANSACTION;
            }

        }

其中红色部分就是调用了spring提供的默认值,而spring的默认值:在jta和cmt中都默认使用的是after_statement

/**
     * Sets connection release mode "on_close" as default.
     * <p>This was the case for Hibernate 3.0; Hibernate 3.1 changed
     * it to "auto" (i.e. "after_statement" or "after_transaction").
     * However, for Spring's resource management (in particular for
     * HibernateTransactionManager), "on_close" is the better default.
     
*/

     public  ConnectionReleaseMode getDefaultReleaseMode()  {
        
return ConnectionReleaseMode.ON_CLOSE;
    }


而spring为什么要使用on_close ,而不是用after_transaction ,我们想想opensessioninview的原理也许能明白,session在view成还要使用,所以不能再transaction使用完后关闭JDBC connection,必须要在session之后,所以要使用on_close也就是在on session(flush.auto,或者flush.Eagerly) 关闭)。这种情况hibernate内部还会在spring关闭JDBC connection后提示(费解,因为after transaction之后session没有关闭,但是 Connection release mode配置的是on_close,session的关闭和 Connection 的关闭都由spring来管理,hibernate就不知道了),所以hibernate有好的提示如下(其实session,已经关闭。当然随着session的关闭jdbc链接释放回连接池):
transaction completed on session with on_close connection release mode; be sure to cl
ose the session to release JDBC resources!,

。当然我们也可以使用after_transaction ,这种情况对使用编程式事务非常适用。

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部