java.sql.SQLException: connection holder is null

 

调试的时候常常会出现这个问题,缘由是事务时间已经达到系统设置的最长值,系统觉得超时,切断这个链接,从而调用事务时发生了错误。java

这个不单单是调试时会发生,再系统中也有发生,好比一个很耗时的流程,由于过程很是耗时,这个耗时操做刚好是在service的事务中发生,事务打开链接必然打开,因此他就会暂用链接的大量时间,致使系统耗时过长(达到链接时长的最大值)而链接断开。spring

或许你会想到调整这个耗时时长:数据库

spring-mybatis.xml服务器

<!-- 清除无用链接的等待时间 --> 网络

<property name="removeAbandonedTimeout" value="600"/>mybatis

 

另外,对于一些数据库链接耗时很长的操做,咱们能够经过 Mybatis 单独设置这个时间,select update insert delete调试

timeout 这个设置是在抛出异常以前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。xml

 

缺陷,因为大部分系统使用声明式事务(Spring的AOP),而非注解式事务(@Transaction),致使全部的非数据库的业务逻辑都用在了事务上,由于事务是加在 Service上,Service就是全部的业务代码集合,因此,不少非数据库操做的逻辑都加了事务,其实彻底没有必要。若是咱们使用注解式事务,那么一些逻辑操做是可控的。事务

    <tx:advice id="txAdvice" transaction-manager="transactionManager">资源

        <tx:attributes>

            <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

            <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

            <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

            <tx:method name="set*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

        </tx:attributes>

    </tx:advice>

 

链接时间太长致使资源浪费,并且超时是一个很友好的设置,若是没有超时设置,无限制等待,虽然能够解决耗时问题,可是若是遇到系统错误,那就会一直等待,暂用资源。

好比这段代码

// 客户端代码

try{

    process() 

    notifyServer()

}catch(Exception e ){

   // do nothing 

}

假设这样的处境,服务端想要知道客户端的坐标,发送一个长链接给客户端,客户端就会执行如上的代码,先去 process 获取当前坐标,而后通知服务器。若是,客户端在获取坐标的时候出现了Exception,好比 GPS信号弱,网络不通等,那么客户端抛出异常被捕获,客户端仍是顺利的执行了代码,却没有通知服务端,咱们这里发生了异常。那么这个时候服务端一直等待客户端的响应,没有超时设置的话,一直占用这个链接,若是有超时的话,达到这个时间,链接就断开了。

相关文章
相关标签/搜索