How to avoid stalled DB connections with TomEE'

2019-07-09 05:22发布

问题:

I'm creating a JSF web app on TomEE1.7.2 (over tomcat7, javaEE6). I have JDBC to mysql5.6.23 connection setting which look like below, and it is working just good, for only some hours.

My data access super class:

public class BaseDao {
    @javax.ejb.EJB
    MyEnvironmentService env;

    @javax.persistence.PersistenceContext(unitName = "persistence-unit-stg")
    protected javax.persistence.EntityManager em_stg;

    @javax.persistence.PersistenceContext(unitName = "persistence-unit-prd")
    protected javax.persistence.EntityManager em_prd;

    protected javax.persistence.EntityManager em;

    @javax.annotation.PostConstruct
    private void init(){
        switch (env.getName()){
            case "stg":
                em = em_stg;
                break;
            case "prd":
                em = em_prd;
                break;
            default:
                throw new RuntimeException("Oh no!");
        }
    }
}

My data access class:

@javax.ejb.Stateless
public class MyDao extends BaseDao{
    public MyEntity find(Object id) {
        return em.find(MyEntity.class, id);
    }
}

My META-INF/persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="persistence-unit-stg" transaction-type="JTA">
        <jta-data-source>mysql-jdbc-jta-resource-stg</jta-data-source>
    </persistence-unit>
    <!-- almost same persistence-unit for prd -->
</persistence>

My WEB-INF/resource.xml:

<?xml version='1.0' encoding='UTF-8'?>
<resources>
    <Resource id="mysql-jdbc-jta-resource-stg" type="javax.sql.DataSource">
        JdbcDriver com.mysql.jdbc.Driver
        JdbcUrl jdbc:mysql://db-stg.bar.someRegion.rds.amazonaws.com/someDBname
        UserName username
        password password
        jtaManaged true
    </Resource>
    <!-- almost same Resource for prd -->
</resources>

I have 2 problems that I want to solve:

1. When I start my web app on staging environment, leave it, and mysql "wait_timeout" comes, my web application gets

javax.transaction.RollbackException: Transaction is marked for rollback

and CANNOT reconnect to mysql again forever. I've already tried some JDBC's autoreconnect=true or autoreconnectForPool=true things, did NOT work either, and I feel like it's not the best thing to do, in the first place (feature already deprecated?) .

2. When I start my web app, I see exactly 3 connections connected to mysql, and everytime, ONLY 1 of the connection is seem to be used and extends its timeout, but other 2 are never used and killed just at the "wait_timeout". I tried "initialSize 10", and it comes with 15 connections, and again, ONLY 1 of the connection is used.

I guess there is a really simple solution for them, because it says:

Internally, from TomEE 1.5.0, JDBC pools are managed via Tomcat-pool.

in this page http://tomee.apache.org/common-datasource-configurations.html

Well yes, I DO want to use this Tomcat JDBC pool ( or something alternative is fine.), it doesn't seem to be enabled. May be I'm missing some xml settings or jar or whatever, but I have no idea. please help me out.

回答1:

I'm successfully using a resources.xml in my WEB-INF folder similar to this one in of my production projects:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<Resource id="mysql-jdbc-jta-resource-stg" type="javax.sql.DataSource">
    JtaManaged = true
    DataSourceCreator = tomcat

    validationQuery = SELECT 1
    initialSize = 2
    removeAbandoned = true
    removeAbandonedTimeout = 120

    driverClassName = com.mysql.jdbc.Driver
    url = jdbc:mysql://db-stg.bar.someRegion.rds.amazonaws.com/someDBname
    username = your-username
    password = your-pw
</Resource>
</resources>

One important difference is to use DataSourceCreator = tomcat. This ensures that TomEE creates a pool which takes care for connection validation ("SELECT 1") and removes stalled/outdated connections, thus freeing up resources in the background.

By contrast, the DataSourceCreator = dbpc (which is default when not set: "Default provided pools are DBCP...") behaved as you described/experienced it (timeouts,...). Check the related documentation for further differences.

Also note, that = is used in my working configuration. I discovered that in previous TomEE releases it seemed to work without =. However, I would recommend to configure with = consistently when your target application server is TomEE 1.7.2 or higher.

Further details on this can also be found in the DataSource Configuration page.

Hope it helps.