zoukankan      html  css  js  c++  java
  • Java问题:Quartz,Hibernate,Spring,Tomcat中定时任务无故停止,没有错误

    最近在做一个java项目的时候遇到一个十分奇怪的问题,想到大家可能也会遇到这样的问题,所以在此发出来,希望大家遇到的时候能够快速解决!

    直入主题

    问题:使用quartz进行定时任务自动执行的时候,用到hibernate进行数据库交互,Tomcat运行中,会遇到在某个访问前后无故停止运行,之后的定时任务全部卡住!

    问题解析:首先我从几个方面考虑这个问题。

    1、quartz配置问题。

    2、数据库连接超时。

    3、Tomcat自动清理或者超时。

    4、quartz线程死锁或阻塞。

    5、hibernate Session问题。

    综合考虑以上问题,一个一个考虑。首先,我的配置是没有问题的,因为quartz的配置还是很清晰和简单的,经过反复查看没有问题。数据库连接在我设置成1s周期的时候也是没有问题的,同时也不会是第三个原因。由于我的quartz的线程设置都是使用默认的,而且我在线程列表中也看到,有10个线程,所以线程不够用导致阻塞是不可能的。死锁的问题我也不用考虑,因为每个任务都是单独存在的,没有关联。那就剩最后一个原因了,说实话,最后一个原因是我没办法的时候才突然想到的,也是问题所在。

    hibernate有自己的连接池,在使用的时候我们新建的所有连接都会存在这个连接池中,如果你所建的新连接太多而不释放,那么就会导致你的新连接无法创建,从而阻塞,这也是为什么程序中无故停止,而且没i有任何错误的原因。

    那么怎么解决这个问题呢,使用Hibernate时,大家一般都记住了配置基本的那些选项,比如方言,缓存等,但是有一项配置卻很容易忘掉,这就是连接释放模式:hibernate.connection.release_mode

    这个配置项有三个选择:after_statement/after_transaction/on_close,javadoc中可以看出它们的用处,注意的一点是,如果不配置,默认是on_close,那么如果沒有显示的去调用session.close或其它关闭连接的方法的话,这个连接时不会被关闭的!在用到连接池的時候,就更会出现问题了,池中的连接会一直存在着而不会被关闭和回收!

    具体的配置:<prop key="hibernate.connection.release_mode">after_transaction</prop>

    放在你的hibernate配置里面就可以了。这样我们的连接自动释放后就不会出现上述问题了。

    PS:这个问题我解决了很长时间,网上的资料查了很多,浪费了很多时间,同时也有人遇到这样的问题,但是解决方式都不太对症。最后发现了这个问题。终于解决了,写在这里,方便大家。尽量不要在这个问题上浪费时间。

    如果帮助到了你,请点赞,谢谢!

     2015 12 16 

    今天又深入的研究了一下,问题的源头是连接池连接阻塞,所以我修改了数据源的连接回收时间,实验有效。具体配置如下,大家可以试试

            <!-- 初始连接数目 -->
            <property name="initialSize" value="10"></property>
            <!-- 最大连接数目 -->
            <property name="maxActive" value="50"></property>
            <!-- 最大空闲连接数目 -->
            <property name="maxIdle" value="50"></property>
            <!-- 最小空闲连接数目 -->
            <property name="minIdle" value="0"></property>
            <!-- 超时等待时间以毫秒为单位 -->
            <property name="maxWait" value="10000"></property>
            <!-- #是否自动回收超时连接 -->
            <property name="removeAbandoned" value="true"></property>
            <!-- #设置被遗弃的连接的超时的时间(以秒数为单位),即当一个连接被遗弃的时间超过设置的时间,则它会自动转换成可利用的连接。默认的超时时间是300秒。 -->
            <property name="removeAbandonedTimeout" value="60"></property>
            <!-- #是否在自动回收超时连接的时候打印连接的超时错误 -->
            <!-- <property name="logAbandoned" value="true"></property> -->
  • 相关阅读:
    雅虎笔试&面试题
    有道面试
    IBM笔试&面试
    20140916~17华宇笔试&面试
    操作系统知识梳理3-存储管理
    操作系统知识梳理2-哲学家就餐问题
    操作系统知识梳理1-概述及进程管理
    阿里面试总结
    2012-2015网易有道笔试题总结
    PostgresSQL在cmd中使用psql操作数据库
  • 原文地址:https://www.cnblogs.com/HJL-Blog/p/5044672.html
Copyright © 2011-2022 走看看