当前位置: 首页 > 知识库问答 >
问题:

如何避免与TomEE的JDBC连接池的DB连接停滞?

蒋高扬
2023-03-14

我正在TomEE1.7.2(通过tomcat7、javaEE6)上创建一个JSF web应用程序。我有JDBC到mysql5.6.23的连接设置,如下所示,它工作得很好,只有几个小时。

我的数据访问超类:

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!");
        }
    }
}

我的数据访问类:

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

我的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>

我的WEB-INF/资源。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>

我有两个问题要解决:

javax.transaction.RollbackException: Transaction is marked for rollback

无法永远重新连接mysql。我已经尝试过一些JDBC的autoreconnect=true或autoreconnectForPool=true的东西,但都不起作用,首先我觉得这不是最好的选择(功能已经被弃用了?)。

2.当我启动我的web应用程序时,我看到有3个连接连接到mysql,每次,似乎只有一个连接被使用并延长了超时时间,但其他2个连接从未被使用并在“wait\u timeout”时被终止。我尝试了“initialSize 10”,它有15个连接,同样,只有一个连接被使用。

我想有一个非常简单的解决方案,因为它说:

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

在本页中http://tomee.apache.org/common-datasource-configurations.html

嗯,是的,我确实想使用这个Tomcat JDBC池(或者其他替代方案也可以),它似乎未启用。可能是我缺少了一些xml设置或jar之类的东西,但我不知道。请帮帮我。

共有1个答案

包修贤
2023-03-14

我正在成功地使用资源。xml在我的WEB-INF文件夹中,类似于我的一个生产项目中的此文件夹:

<?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>

一个重要的区别是使用DataSourceCreator=tomcat。这确保了TomEE创建一个池来处理连接验证(“SELECT 1”)并删除停滞/过时的连接,从而释放后台资源。

相比之下,DataSourceCreator=dbpc(未设置时为默认值:“默认提供的池是DBCP…”)按照您的描述/经历行事(超时…)。检查相关文档以了解更多差异。

还要注意,我的工作配置中使用了=。我发现在以前的TomEE版本中,它似乎在没有代码的情况下也能工作。但是,当您的目标应用程序服务器是TomEE 1.7.2或更高版本时,我建议您一致地配置。

有关这方面的更多详细信息,也可以在数据源配置页面中找到。

希望有帮助。

 类似资料:
  • 问题内容: 我在GlassFish上有一个Java-JSF Web应用程序,我想在其中使用连接池。因此,我创建了一个有范围的Bean,可与其他Bean的实例一起使用: 这样,连接池很快就会被填满。在“ db-related”视图中进行几次导航后,应用程序将停止以下操作: RAR5117:无法从连接池[mysql_testPool]获取/创建连接。原因:使用中的连接等于最大池大小和已过期的最大等待时

  • 我编写了以下代码来连接到Oracle数据库。这用于REST API。我正在连接的数据库的IDLE_TIME参数设置为30分钟(这不能更改)。如果数据库连接空闲超过30分钟,则会抛出以下错误:“java.sql.SQLRecoverableException: ClosedConnection”。抛出此错误后,API将停止工作。我如何解决这个问题?

  • null 任何想法都将受到赞赏。

  • 我有一个问题,在通过tomcat web应用程序应用户请求重置MySQL数据库后,我会收到tomcat异常。到目前为止,我已尝试将其分解为设置、问题和我的分析,以帮助任何试图阅读本文的人。 重置基本上包括从java代码调用bash脚本以: 删除根mysql用户密码 加载数据库的旧版本 在上面运行一些脚本 恢复所有密码 这是一个用户启动的过程,通常将数据库恢复到以前的状态,但它也用于从另一个系统导入

  • 我们有一个spring-boot应用程序,它使用嵌入式tomcat进行部署,并使用MySQL后端的默认tomcat-jdbc连接池,而没有为MySQL或tomcat端定制。 该应用程序有一些调度程序,它们主要在一天中的特定时间运行,即在昨天的最后一次cron运行和今天的第一次cron运行之间,有超过9个小时的间隙。然而,无论何时cron在早期运行,它都从未遇到过空闲连接问题。 现在我们看到一条错误

  • Tomcat JDBC连接池提供了几个测试连接的选项。我觉得更有趣的两个是和。 首先,我认为是最好的选择,因为它基本上是在将连接提供给应用程序之前验证连接(最大频率由定义)。 但是过了一会儿,我意识到在使用连接之前测试它可能会影响应用程序的响应性。因此,我认为使用可以更有效,因为它在不使用连接时测试连接。 另一方面,我很惊讶不适用于,而且我并不真正理解的用途。