我在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安装,没有调整或自定义配置。如何微调基础设施以避免这些问题?
答案 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服务:不再存在锁定问题。