如何微调JPA / JAX-RS应用程序

时间:2016-04-28 07:16:25

标签: java hibernate jpa jax-rs database-connection

我在Wildfly / RESTeasy中使用JPA / Hibernate后端开发了一个JAX-RS JSON API,我遇到了严重的数据库访问问题。

例如,突然应用程序停止响应并且日志显示了一堆:

ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 4) IJ031012: Unable to obtain lock in 60 seconds: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection

INFO  [org.jboss.jca.core.connectionmanager.listener.TxConnectionListener] IJ000302: Unregistered handle that was not registered: org.jboss.jca.adapters.jdbc.jdk7.WrappedConnectionJDK7

WARN  [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] IJ000609: Attempt to return connection twice: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener

WARN  [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (default task-9) IJ030020: Detected queued threads during cleanup

ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (ForkJoinPool.commonPool-worker-0) IJ031041: Connection handle has been closed and is unusable

ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (ForkJoinPool.commonPool-worker-1) IJ031050: The result set is closed

我认为这是由于不同用户多次访问(例如15个,20个用户同时访问),因为有一个/两个用户没有这种情况。

我正在使用Hibernate 5.1和Wildfly 10以及SQL Server 2014.它是一个vanilla安装,没有调整或自定义配置。如何微调基础设施以避免这些问题?

2 个答案:

答案 0 :(得分:0)

使用HikariCP连接池。 根据您的流量,在连接池和数据库中配置连接数。 在连接池中,可以选择始终保持一些可用的连接数量。并且还将连接隔离类型设置为仅在提交之后。

下面是它的样本,

<persistence-unit name="sample" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>

            <!-- provider -->
            <property name="hibernate.connection.provider_class" value="com.xo.web.persistence.XOHikariCPConnectionProvider"/>

            <!-- Hibernate properties -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.archive.autodetection" value="hbm" />
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="show_sql"  value="false"/>
            <property name="hibernate.connection.release_mode" value="after_transaction"/>
            <property name="hibernate.connection.autocommit" value="false"/>
            <property name="hibernate.connection.isolation" value="2"/>
            <property name="hibernate.ejb.interceptor" value="com.xo.web.persistence.intercept.XoEntityInterceptor"/>
            <property name="hibernate.jdbc.batch_size" value="100"/>
            <property name="hibernate.order_inserts" value="true"/>
            <property name="hibernate.order_updates" value="true"/>


            <!-- Hikari settings -->
            <property name="maximumPoolSize" value="80" />
            <property name="autoCommit" value="false" />
            <property name="minimumPoolSize" value="20" />
            <property name="idleTimeout" value="60000" />
            <property name="maxLifetime" value="600000" />
            <property name="connectionInitSql" value="select 1" />
            <property name="connectionTimeout" value="1000" />
            <property name="validationTimeout" value="1000" />
            <property name="cachePrepStmts" value="true" />
            <property name="prepStmtCacheSize" value="250" />
            <property name="prepStmtCacheSqlLimit" value="2048" />

        </properties>
    </persistence-unit> 

答案 1 :(得分:0)

问题与REST服务@Stateless有关,因此在每个请求上打开事务。解决方案是将@Stateless DAO注入REST服务:不再存在锁定问题。