2012-10-25 26 views
2

我的應用程序使用JPA(Hbernate ORM)連接到部署在JBoss AS 7.x服務器上的SQL Server 2008。如果網絡出現故障,再次來到了,我得到了以下異常如何在JBoss AS 7.x網絡故障後重新建立連接-JPA

14:59:27,996 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: The connection is closed. 
14:59:28,002 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361) 
14:59:28,012 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289) 
14:59:28,020 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:261) 
14:59:28,025 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at com.honeywell.domoweb.dataservice.dao.impl.UserDaoImpl.getUsers(UserDaoImpl.java:372) 
14:59:28,030 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
14:59:28,034 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
14:59:28,039 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
14:59:28,044 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at java.lang.reflect.Method.invoke(Method.java:597) 
14:59:28,047 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) 
14:59:28,052 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
14:59:28,058 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
14:59:28,064 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 
14:59:28,069 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
14:59:28,075 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
14:59:28,080 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at $Proxy66.getUsers(Unknown Source) 
14:59:28,083 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at com.honeywell.domoweb.dataservice.dao.impl.TemplateDaoImpl.getTemplate(TemplateDaoImpl.java:44) 
14:59:28,089 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)... 

我GOOGLE了這個問題,並發現這一問題需要在連接池的配置使用autoReconnect的屬性再次重新連接的變化,但沒「噸發現任何例如,如何與我的連接池settings.Below嵌入autoReconnect的是在Standalone.xml我的連接池的設置文件

<subsystem xmlns="urn:jboss:domain:datasources:1.0"> 
     <datasources> 


      <datasource jndi-name="java:jboss/datasources/DataServiceDS" pool-name="dataServicePool" enabled="true" use-java-context="true"> 
       <connection-url>jdbc:sqlserver://ipaddress:1433;databaseName=myDataBase</connection-url> 
       <driver>sqlserver</driver> 
       <pool> 
        <min-pool-size>10</min-pool-size> 
        <max-pool-size>100</max-pool-size> 
        <prefill>true</prefill> 
       </pool> 
       <security> 
        <user-name>usename</user-name> 
        <password>password</password> 
       </security> 
      </datasource> 
      <drivers> 

       <driver name="sqlserver" module="com.microsoft.sqlserver"> 
        <xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</xa-datasource-class> 
       </driver> 
      </drivers> 
     </datasources> 
    </subsystem> 

可否請您讓我知道,如何重新連接到數據庫,如果網絡出現故障並重新連接?

回答

2

你想解決什麼問題?

如果您試圖在「網絡故障」時停止交易失敗。這是不可能的。您需要查看「XA」和SQL集羣來解決該問題的某些部分。但我不認爲你正在尋找這個。

..

如果你想從他們是否有足夠的不幸是空閒的SQL連接到JBoss中的連接池是保持的第一個用戶不停止應用程序操作。那麼是的,你可以做些什麼。

的問題是:

  • 的Windows默認情況下,斷開活動的TCP連接時,「網絡出現故障」其他平臺不這樣做。對於你,我猜想只有一部分網絡出現故障,這意味着SQL服務器如果受到影響就會結束,而不是JBoss結束。

  • JBoss端的連接池將保持TCP連接在池中的空閒連接打開。 JBoss端不知道網絡關閉,它可能會短時間與SQL服務器失去聯繫。當網絡出現時,SQL服務器端重置/丟失所有連接。但是JBoss的終端仍然有「半開放的連接」,它仍然認爲連接是有效的。

  • 在需要使用SQL之前,JBoss可能會在一段時間內空閒(秒/分鐘/小時)。然後它得到一個SQL句柄,並且連接池適時地從閒置的池中返回一個。不知道TCP連接已經死亡。應用程序然後使用它來找出TCP連接被重置,以響應某些數據從客戶端發送到服務器和服務器,並說'我沒有打開連接'。這會強制SQL驅動程序關閉連接並開始將SQLException返回到JDBC句柄上的操作。

所以下面我籠統地談論如何幫助緩解或解決問題,請諮詢您的支持渠道和SQL文件:

觀光考慮:

  • 你的連接池塘文件。我相信JBoss提供了自己的連接池實現。所以雖然這個問題可以在連接池中解決,但不清楚連接池是否與你的JBoss版本以及你正在使用的連接池可能具有適當的功能。

  • 啓用TCP保持活動,這些是TCP協議執行的低級ping/pong,通常可以在幾秒鐘內完成。默認情況下,1小時對於SQL來說可能太長,可能5分鐘更好。

  • 啓用的連接池,以檢查/驗證連接是它給應用程序之前良好和有效的。這可能會使用內部ping/pong檢查,或者可能會執行「SELECT 1」。這可能是最簡單的/最快的解決方案,完全解決了這個問題,但是然後可以在使用前將額外的往返可觀的性能影響。

  • 啓用僅當連接已經閒置超過某些限制(也許60秒)長的上述點。這可減輕SQL在相當閒置時啓用時的性能影響。

  • 看看你的SQL驅動程序支持自定義的TCP數據平/乒乓機制,看看的連接池實現支持使用它。

  • 使用簡短的最大空閒時間。

  • 下空閒連接的最大數目。

  • 如果連接不在事務中並且如果這是第一個失敗的語句(通常唯一的選項更改是autocommit = off,那麼'BEGIN TRANSACTION'這種情況對於驅動程序來說可能會檢測到並無縫地恢復)。

建議步驟也許看C3P0的連接池,如果你有一個選擇,選擇外部的第三方開源緩衝池使用。這在JBoss環境中可能並非如此。

6

您可以添加

<check-valid-connection-sql>select 1 </check-valid-connection-sql> 

到數據源配置,或任何你想要的其他SQL語句。 這個sql語句將在連接池每次從連接池檢出時執行,並且如果語句失敗,即連接被關閉,它將被銷燬並重新創建/重新連接到sql server。這將確保您的應用程序(hibernate)始終能夠正常工作。

3

也有難以找到類似問題的例子。對於jboss7添加了以下幾行數據源配置

<datasource> 
    ... 
    <validation> 
    <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql> 
    <validate-on-match>false</validate-on-match> 
    <background-validation>true</background-validation> 
    </validation> 
    ... 
</datasource>