Eclipselink, c3p0 и Spring - создание слишком большого количества соединений! - PullRequest
2 голосов
/ 06 апреля 2011

Я пытаюсь использовать c3p0 для объединения моих подключений к БД MySQL с Eclipselink , но я столкнулся с проблемой. При запуске сервера Virgo создается правильное количество соединений c3p0 initialPoolSize, но каждый раз, когда используется EntityTransaction , создается дополнительное соединение - даже выше и выше установленного c3p0 maxPoolSize.

Очевидно, что это проблема, так как максимальное количество соединений быстро достигается, но, поскольку я относительно новичок в этой настройке, мне трудно определить, где находится ошибка. Я прикрепил используемые мной файлы конфигурации, надеясь, что один из вас может увидеть, где я вводил ошибку!

JPA, используемый для сохранения объекта:

public class JpaTbRepository {

    private final EntityManagerFactory emf;    
    public JpaTbRepository(EntityManagerFactoryBuilder builder,
                                    Map<String, Object> properties) {
        this.emf = builder.createEntityManagerFactory(properties);
    }

    public JpaTbRepository(EntityManagerFactory entityManagerFactory) {
        this.emf = entityManagerFactory;
    }

    @Override
    public void save(TbObject tb) {      

        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            TbObjectEntity tbEntity = TbObjectEntity.valueOf(tb);
            em.persist(tbEntity);
            em.getTransaction().commit();
        } finally {
            em.close();
        }
    }
}

Тогда контекст приложения:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:p="http://www.springframework.org/schema/p" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                           http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd">

    <!--
        Activates various annotations to be detected in bean classes: Spring's
        @Required and @Autowired, as well as JSR 250's @PostConstruct,
        @PreDestroy and @Resource (if available) and JPA's @PersistenceContext
        and @PersistenceUnit (if available).
    -->
    <context:annotation-config />

    <context:property-placeholder properties-ref="config" ignore-unresolvable="true" system-properties-mode="NEVER"  />
    <osgix:cm-properties id="config" persistent-id="org.olanb" />

    <bean id="databaseConfig" class="org.olanb.ConfigurationPropertyPlaceholderConfigurer">
        <property name="queryPath" value="Database" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_NEVER" />
    </bean>

    <bean id="connPoolConfig" class="org.olanb.ConfigurationPropertyPlaceholderConfigurer">
        <property name="queryPath" value="Database/ConnectionPool" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_NEVER" />
    </bean>

    <bean id="dataSource" 
          class="com.mchange.v2.c3p0.ComboPooledDataSource" 
          destroy-method="close"
          p:driverClass="com.mysql.jdbc.Driver"
          p:jdbcUrl="jdbc:mysql://${PrimaryHost},${SecondaryHost}/${Schema}?autoReconnect=true&amp;failOverReadOnly=false"
          p:user="user"
          p:password="pass"
          p:initialPoolSize="5" 
          p:minPoolSize="5" 
          p:maxPoolSize="10"
          p:maxStatements="20" />           

    <bean id="tbRepository" class="org.olanb.JpaTbRepository">
      <constructor-arg ref="entityFactoryBuilder" />
      <constructor-arg ref="databaseProperties" />
    </bean>

    <util:map id="databaseProperties" map-class="java.util.HashMap">
        <entry key="javax.persistence.nonJtaDataSource" value-ref="dataSource"/>
        <entry key="eclipselink.target-database" value="MySQL" />
        <entry key="eclipselink.jdbc.read-connections.min" value="1" />
        <entry key="eclipselink.jdbc.write-connections.min" value="1" />
        <entry key="eclipselink.jdbc.batch-writing" value="JDBC" />
        <entry key="eclipselink.ddl-generation" value="create-tables" />
        <entry key="eclipselink.ddl-generation.output-mode" value="database" />
        <entry key="eclipselink.logging.level" value="INFO" />
        <entry key="eclipselink.logging.thread" value="false" />
        <entry key="eclipselink.logging.session" value="false" />
        <entry key="eclipselink.logging.exceptions" value="true" />
        <entry key="eclipselink.logging.timestamp" value="false" />
        <entry key="eclipselink.cache.shared.default" value="false" />
    </util:map>

</beans>

Кроме того, это используется в пакете OSGi, поэтому контекст OSGi xml:

<?xml version="1.0" encoding="UTF-8"?>
<bean:beans xmlns="http://www.springframework.org/schema/osgi"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:bean="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                            http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">


<service ref="tbRepository" interface="org.olanb.api.tbRepository"/>

<service ref="catalog" interface="org.olanb.Catalog" />

<reference id="entityFactoryBuilder" 
           interface="org.osgi.service.jpa.EntityManagerFactoryBuilder" 
           filter="(osgi.unit.name=olanb.jpa)">
</reference>

И, наконец, файл persistence.xml выглядит примерно так:

<persistence version="1.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_1_0.xsd">
    <persistence-unit name="olanb.jpa">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>org.olanb.tbEntity</class>
    </persistence-unit>
</persistence>

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Одд.Вы уверены, что создается только один из ваших JpaTbRepository?Может быть, вы получаете несколько созданных и несколько пулов, созданных каким-то образом.Попробуйте добавить отладку и включите лучший вход в EclipseLink.

Обратите внимание, что

<entry key="eclipselink.jdbc.read-connections.min" value="1" />
<entry key="eclipselink.jdbc.write-connections.min" value="1" />

не следует использовать при использовании источника данных, и его следует удалить.

1 голос
/ 13 апреля 2011

Спасибо Джеймсу за ответ и информацию.Ваш первоначальный ответ был довольно точным!Это было странно.Мне удалось изолировать проблему в URL C3p0 JDBC MySQL.Я обнаружил, что на вторичном хосте пул соединений не работает, но с удаленным вторичным хостом он работает!

Если посмотреть дальше, то обнаружил ошибку в этой области с версией драйвера Connector / JЯ использовал (5.1.13), поэтому я обновил (до 5.1.15), и он работал со вторичным хостом!

Список изменений, который исправляет ошибку: http://dev.mysql.com/doc/refman/5.1/en/cj-news-5-1-14.html

Заключение: Решено обновлением Connector / J до v5.1.15

...