5 Stimmen

Wiederherstellung der Jboss-Datenquelle nach Neustart der Datenbank

Geschlossene Verbindungen noch im Verbindungspool - warum?

servlet-

public class Index extends HttpServlet {

    TimeZoneService timeZoneService;

    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException {
        WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        timeZoneService = (TimeZoneService) ctx.getBean("timeZoneService");
        timeZoneService.loadAllTimeZones();
        System.out.println("Done");
    }
}

public interface TimeZoneService {
    void loadAllTimeZones();
}

public class TimeZoneServiceImpl implements TimeZoneService {

    private TimeZoneDao tzDao;
    private Map<Long, String> tzOid2JavaName = new HashMap<Long, String>();

    public void loadAllTimeZones() {
        List<TimeZone> timeZones = tzDao.findAllTimeZones();
        for (TimeZone tz : timeZones) {
            tzOid2JavaName.put(tz.getOid(), tz.getJavaName());
        }
    }

    public void setTzDao(TimeZoneDao tzDao) {
        this.tzDao = tzDao;
    }
}

public interface TimeZoneDao {
    List<TimeZone> findAllTimeZones() throws DataAccessException;  
}

public class TimeZoneDaoImpl extends JdbcDaoSupport implements TimeZoneDao {

    public List<TimeZone> findAllTimeZones() throws DataAccessException
    {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT TZ.OID, TZ.JAVA_NAME FROM TIME_ZONE TZ");
        List<TimeZone> timeZones = getJdbcTemplate().query(sql.toString(), new RowMapper() {
            public Object mapRow(ResultSet rs, int i) throws SQLException {
                TimeZone tz = new TimeZone();
                tz.setOid(rs.getLong("OID"));
                tz.setJavaName(rs.getString("JAVA_NAME"));
                return tz;
            }
        });

        return timeZones;
    }
}

public class TimeZone {
    private Long oid;
    private String javaName;

    public Long getOid() {
        return this.oid;
    }

    public void setOid(Long oid) {
        this.oid = oid;
    }

    public String getJavaName() {
        return this.javaName;
    }

    public void setJavaName(String javaName) {
        this.javaName = javaName;
    }
}

spring-config.xml

<beans>

    <jee:jndi-lookup id="dataSource" jndi-name="java:/OracleDS"/>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="timeZoneDao" class="dao.impl.TimeZoneDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="timeZoneService" class="logic.impl.TimeZoneServiceImpl">
        <property name="tzDao" ref="timeZoneDao"/>
    </bean>

</beans>

web.xml

<web-app>

    <display-name>Spring</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            WEB-INF/spring-config.xml,classpath*:/META-INF/spring-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>index</servlet-name>
        <display-name>Index page</display-name>
        <description>Landing page</description>
        <servlet-class>servlet.Index</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>index</servlet-name>
        <url-pattern>/index</url-pattern>
    </servlet-mapping>

    <!-- Session Timeout (in minutes) -->
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

mysql-ds.xml

<datasources> 
   <local-tx-datasource> 
      <jndi-name>OracleDS</jndi-name> 
      <connection-url>jdbc:mysql://localhost:3306/spring</connection-url> 
      <driver-class>com.mysql.jdbc.Driver</driver-class> 
      <user-name>spring_test</user-name> 
      <password>spring_test13</password> 
      <min-pool-size>1</min-pool-size> 
      <max-pool-size>5</max-pool-size> 
      <idle-timeout-minutes>2</idle-timeout-minutes> 
   </local-tx-datasource> 
</datasources>

0 Stimmen

Mysql-ds.xml <datasources> <local-tx-datasource> <jndi-name>OracleDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/spring</connection-url> <driver-class>com.mysql.jdbc. Driver</driver-class> <user-name>spring_test</user-name> <password>spring_test13</password> <min-pool-size>1</min-pool-size> <max-pool-size>5</max-pool-size> <idle-timeout-minutes>2</idle-timeout-minutes> </local-tx-datasource> </datasources>

8voto

Prasanth Punkte 181

Ok. Ich hoffe, das Folgende ist für jemanden nützlich :-)

Es gibt eine Konfigurationseinstellung für die Datenquelle - exception-sorter-class-name

Nach Angaben von Jboss wird dies verwendet für a class that looks at vendor specific messages to determine whether sql errors are fatal and thus the connection should be destroyed. If none specified, no errors will be treated as fatal.

Wenn Verwendung der Oracle-Datenbank wird diese Konfiguration eingestellt auf org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter . Diese Klasse enthält alle Fehlercodes, die als schwerwiegend behandelt werden müssen, so dass die Verbindung zerstört werden muss.

In Jboss 4 sind die Fehlercodes 17002 (Verbindung zurückgesetzt) && 17008 (Verbindung geschlossen) nicht enthalten. Sie werden in Jboss 5 hinzugefügt. Wenn Sie also Jboss 4 verwenden und sich fragen, warum die Verbindungen nicht wiederhergestellt werden, versuchen Sie, die fehlenden Codes hinzuzufügen.

3voto

Nikita Koksharov Punkte 9489

Hier ist die Konfiguration der Verbindungsvalidierung mit Oracle DB für jboss 7.1+ :

<validation>
   <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.vendor.OracleValidConnectionChecker"/>
   <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
   <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.vendor.OracleStaleConnectionChecker"/>
   <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
</validation>

Jetzt wird Jboss jede Verbindung validieren.

2voto

skaffman Punkte 389758

Dies ist ein häufiges Problem, das bei der Verwendung eines Verbindungspools auftritt. Wenn die Anwendung eine Verbindung aus dem Pool ausleiht, sollte der Pool selbst die Verbindung "testen", um sicherzustellen, dass sie noch gültig ist, oder sollte er dies der Anwendung überlassen?

Wenn der Pool die Verbindung testet, bedeutet dies unweigerlich, dass er etwas über die Verbindung an den Datenbankserver sendet (in der Regel ein einfaches SELECT irgendeiner Art). Auf Systemen mit hohem Datenverkehr ist dies eine enorme Verschwendung und kann den Datenbankserver erheblich belasten.

Bei Websites mit geringem Datenverkehr, bei denen Ihre Datenbank die zusätzliche Last bewältigen kann, können Sie Ihre Datenquelle so konfigurieren, dass JBoss die Verbindung validiert, bevor sie an Ihre Anwendung weitergegeben wird. Wenn die Verbindung tot ist, entfernt JBoss sie aus dem Pool und erhält eine neue, so dass sie einen Neustart der Datenbank übersteht.

Any, fügen Sie dies zu Ihrem mysql-ds.xml Datei:

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

Sie müssen die Abfrage selbst auswählen und darauf achten, dass sie nicht zu teuer ist, denn es wird ein Los .

Siehe die JBoss-Dokumentations-Wiki um zu sehen, wie Sie diese Datenquellendateien ändern können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X