Почему Tomcat подключает пул выхлопных соединений при использовании Spring MVC и Eclipselink

Я разработал веб-приложение. Я использую Spring MVC, Eclipselink, MariaDB 10, Tomcat 8/9. Это может хорошо работать в течение некоторого времени после запуска Tomcat. Но по мере увеличения соединения в журнале Tomcat возникает следующая ошибка:

java.sql.SQLNonTransientConnectionException: (conn = 94) Соединение закрыто java.sql.SQLException: Соединение уже закрыто

Веб-сайт все еще может работать в течение некоторого времени, но поскольку эта ошибка встречается чаще, веб-сайт полностью не работает. Кажется, что соединения Tomcat исчерпаны.

Любой комментарий будет оценен!

Ниже приведены мои настройки и код Java:

Настройка весеннего мвк

<jee:jndi-lookup id="dataSource"
    jndi-name="java:comp/env/myDataSourceJNDI"
    expected-type="javax.sql.DataSource" />

<bean id="myEntityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="myserver" />

     <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="databasePlatform" value="MYSQL" />
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
    </property>
</bean>

<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEntityManagerFactory" />
</bean>

<tx:annotation-driven transaction-manager="myTxManager"/>

<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="100" />
    <property name="maxPoolSize" value="200" />
    <property name="queueCapacity" value="500" />
</bean>

persistence.xml

<persistence-unit name="myserver" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>  
    <class>com.sap.it.sr.entity.Employee</class>
        <properties>
        <property name="eclipselink.weaving" value="static"/>
        <property name="eclipselink.jdbc.batch-writing" value="JDBC" />
        <property name="eclipselink.jdbc.batch-writing.size" value="1000" />
        <property name="eclipselink.jdbc.cache-statements" value="true" />
        <property name="eclipselink.jdbc.cache-statements.size" value="500" />
        <property name="eclipselink.jdbc.allow-native-sql-queries" value="true"/>
        <!-- EclipseLink should create the database schema automatically -->
        <property name="eclipselink.ddl-generation" value="create-tables" />
        <property name="eclipselink.ddl-generation.output-mode" value="database" />

        <property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.CommonsLoggingSessionLog" />
        <property name="eclipselink.logging.level.sql" value="INFO"/>
        <property name="eclipselink.logging.parameters" value="true"/>
        <property name="eclipselink.logging.level" value="INFO" />
    </properties>
</persistence-unit>

Настройка JNDI в контексте Tomcat

<Resource 
  name="myDataSourceJNDI" 
  auth="Container" 
  type="javax.sql.DataSource"
  factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  validationQuery="SELECT 1 FROM dummy"
  initialSize="10"
  maxIdle="50"
  maxActive="100"
  minIdle="10"
  maxWait="10000"
  removeAbandoned="true"
  timeBetweenEvictionRunsMillis="5000"
  username="root"
  password="123" 
  driverClassName="org.mariadb.jdbc.Driver"
  url="jdbc:mysql://mariadbserver:3306/mydb" />

Java-кодопределяет менеджер сущностей в классе

@Autowired
@PersistenceContext(unitName="myserver")
protected EntityManager em;

public T merge(T t) {
    try {
            return em.merge(t);
        } catch (Exception e) {
            LOGGER.warn("Merge data failed.");
            e.printStackTrace();
            return null;
        }
}

вызов jpa сохранится в классе контроллера

@RequestMapping(value="/upsert", method = RequestMethod.POST)
@ResponseBody
@Transactional
public void upsertEmployee(@RequestBody Employee emp){
    LOGGER.info("---- Employee.upsert ----");
    if (null != role && (role.equals("1") || role.equals("2"))) {
        Employee emp1 = dao.findByEmpId(emp.getEmpId());
        if (emp.getEmpId() != null) {
            if (emp1.getId() != null) {
                emp.setId(emp1.getId());
            }
            emp.setEmpId(emp.getEmpId().toUpperCase());
            LOGGER.info("---- Employee.upsert -> merge data ----");
            dao.merge(emp);
        }
    }
    LOGGER.info("---- Employee.upsert end ----");
}

0 ответов

Другие вопросы по тегам