jdbc:Could not open Hibernate Session for transaction

頭天在公司還沒有問題,第二天來就報這個錯誤

09:11:37,931 ERROR DefaultDispatcherErrorHandler:42 - Exception occurred during processing request: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed: 
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed: 
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:541)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at com.sunshine.service.StaffService$$EnhancerBySpringCGLIB$$df3b14d.login(<generated>)


具體解釋是這樣的:Mysql服務器默認的“wait_timeout”是8小時【也就是默認的值默認是28800秒】,也就是說一個connection空閒超過8個小時,Mysql將自動斷開該connection,通俗的講就是一個連接在8小時內沒有活動,就會自動斷開該連接。
wait timeout的值可以設定,但最多隻能是2147483,不能再大了。也就是約24.85天
所以即使你MySQL通過my.ini 在

# The TCP/IP Port the MySQL Server will listen on
port=3306下面
添加
# this is myown dinifition for mysql connection timeout
wait_timeout=31536000
interactive_timeout=31536000
無論超過最大限度多大的數值,只能被MySQL解析爲2147483,2147483天后你的程序該出什麼錯還是什麼錯,避免不了的

具體操作:在數據庫操作系統(我的是Navicat)中寫查詢修改語句

通過下面命令可以查看mysql的超時時間

[sql] view plain copy
  1. show global variables like 'wait_timeout';  

其默認值爲8小時,超過這個時間,mysql會自動斷開該連接。

有兩種方法可以修改該值

1、命令修改

[sql] view plain copy
  1. set global wait_timeout=2147483;  
2、修改my.cnf文件
[plain] view plain copy
  1. [mysqld]   
  2. wait_timeout=2147483  
然後重啓mysql



後來發現Hibernate的內置連接池性能是非常的差,還不如直接用第三方的c3p0,改用C3P0連接池,這

個連接池會自動 處理數據庫連接被關閉的情況。要使用C3P0很簡單,先從Hibernate裏把c3p0-0.9.1.jar復

制到項目的lib目錄中,再在 hibernate.properties裏去掉hibernate.c3p0開頭的那些屬性的註釋(使用缺

省值或自己需要的數值),這樣 Hibernate就會自動使用C3P0代替內置的連接池了。到目前爲止前面的問題

沒有再出現過。 
具體在hibernate.cfg.xml中配置如下

 

Xml代碼  收藏代碼
  1. <span style="font-size: medium;"><property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>  
  2.         <!--連接池的最小連接數-->   
  3.         <property name="hibernate.c3p0.min_size">5</property>  
  4.         <!--最大連接數-->   
  5.         <property name="hibernate.c3p0.max_size">30</property>  
  6.         <!--連接超時時間-->  
  7.         <property name="hibernate.c3p0.timeout">1800</property>  
  8.         <!--statemnets緩存大小-->   
  9.         <property name="hibernate.c3p0.max_statements">100</property>  
  10.         <!--每隔多少秒檢測連接是否可正常使用  -->   
  11.         <property name="hibernate.c3p0.idle_test_period">121</property>  
  12.         <!--當池中的連接耗盡的時候,一次性增加的連接數量,默認爲3-->   
  13.         <property name="hibernate.c3p0.acquire_increment">1</property>  
  14.         <property name="hibernate.c3p0.validate">true</property></span>
 

MySQL 的默認設置下,當一個連接的空閒時間超過8小時後,MySQL 就會斷開該連接,而 c3p0 連接池則以爲該被斷開的連接依然有效。在這種情況下,如果客戶端代碼向 c3p0 連接池請求連接的話,連接池就會把已經失效的連接返回給客戶端,客戶端在使用該失效連接的時候即拋出異常。

解決方案:

①:增加 MySQL 的 wait_timeout 屬性的值。修改 /etc/mysql/my.cnf 文件,在 [mysqld] 節中

        # Set a connection to wait 8 hours in idle status.
      wait_timeout = 86400

②:減少連接池內連接的生存週期,使之小於上一項中所設置的 wait_timeout 的值。
       修改 c3p0 的配置文件,設置<property name="maxIdleTime" value="3600" />

③: 定期使用連接池內的連接,使得它們不會因爲閒置超時而被 MySQL 斷開。
        修改 c3p0 的配置文件,設置:

       <bean id="dataSource"    class="com.mchange.v2.c3p0.ComboPooledDataSource">   

                  <property name="preferredTestQuery"        value="'SELECT 1'"/>   

                  <property name="idleConnectionTestPeriod"        value="18000" />   

                  <property name="testConnectionOnCheckout"        value="true" />   

                  <!-- other properties -->

       </bean>

如果其他數據支持重連接可以在URL後加上:

jdbc:mysql://localhost:3306/xxx?useUnicode=true&amp;characterEncoding=utf-8&amp;autoReconnect=true



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章