java - 使用 Spring EntityManager,使用 DBCP 测试死锁

标签 java spring hibernate jpa

我们有一个 JPA 项目,我们正在将其迁移到使用 Spring Entity Manager 而不是标准 Hibernate。目前我们仍然管理自己的交易。当我们转移到 Spring 并使用 DriverManagerDataSource 进行测试时,一切正常(内存数据库中的 H2),但是,当我们更改为 DBCP 或 c3p0 时,在运行等于连接池大小的测试数量后,测试会挂起。 我们正在使用 Try with Resources 来调用 close。

这是我们的一些应用程序上下文:

<bean id="inMemoryDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
      p:driverClassName="org.h2.Driver"
      p:url="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"
      p:username="sa"
      p:password=""
      p:maxTotal="10"
      p:logAbandoned="true"
      p:removeAbandonedTimeout="60"
      p:removeAbandonedOnBorrow="true">
</bean>

<alias name="inMemoryDataSource" alias="connectionDataSource"/>

<bean id="entityManagerFactory"       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="connectionDataSource"/>
    <property name="persistenceUnitName" value="jpaPersistenceUnit" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
              p:showSql="false"
              p:generateDdl="false"
              p:database="H2"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
        </props>
    </property>
</bean>

线程转储:

2014-11-16 17:08:26,644 DEBUG [main] access.TransactionalDataAccessLayer(67): Closing entity manager
2014-11-16 17:08:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.55-b03 mixed mode):

"Monitor Ctrl-Break" daemon prio=6 tid=0x000000000a72a800 nid=0x3fac runnable [0x000000000c56e000]
   java.lang.Thread.State: RUNNABLE
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.read(SocketInputStream.java:152)
      at java.net.SocketInputStream.read(SocketInputStream.java:122)
      at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
      at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
      at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
      - locked <0x00000007ded9cfb8> (a java.io.InputStreamReader)
      at java.io.InputStreamReader.read(InputStreamReader.java:184)
      at java.io.BufferedReader.fill(BufferedReader.java:154)
      at java.io.BufferedReader.readLine(BufferedReader.java:317)
      - locked <0x00000007ded9cfb8> (a java.io.InputStreamReader)
      at java.io.BufferedReader.readLine(BufferedReader.java:382)
      at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:88)
      at java.lang.Thread.run(Thread.java:745)

"Service Thread" daemon prio=6 tid=0x000000000a6cd800 nid=0x3ccc runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x000000000a6c6800 nid=0x2e64 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x000000000a6c5000 nid=0x40c0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" daemon prio=10 tid=0x000000000a69e000 nid=0x3ec runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x000000000a69b000 nid=0xfe8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=8 tid=0x00000000023a0800 nid=0x4350 in Object.wait() [0x000000000ba2f000]
   java.lang.Thread.State: WAITING (on object monitor)
      at java.lang.Object.wait(Native Method)
      - waiting on <0x00000007824e29b8> (a java.lang.ref.ReferenceQueue$Lock)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
      - locked <0x00000007824e29b8> (a java.lang.ref.ReferenceQueue$Lock)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
      at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

"Reference Handler" daemon prio=10 tid=0x000000000a694000 nid=0x32dc in Object.wait() [0x000000000b92f000]
   java.lang.Thread.State: WAITING (on object monitor)
      at java.lang.Object.wait(Native Method)
      - waiting on <0x00000007824e2630> (a java.lang.ref.Reference$Lock)
      at java.lang.Object.wait(Object.java:503)
      at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
      - locked <0x00000007824e2630> (a java.lang.ref.Reference$Lock)

"main" prio=6 tid=0x00000000022b8800 nid=0xf24 waiting on condition [0x000000000229d000]
   java.lang.Thread.State: WAITING (parking)
      at sun.misc.Unsafe.park(Native Method)
      - parking to wait for  <0x0000000781cca690> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
      at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:524)
      at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:438)
      at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
      at org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:119)
      at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1413)
      at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139)
      at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380)
      at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228)
      at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
      at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
      at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162)
      at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435)
      at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61)
      at com.intel.aa.smoove.access.TransactionalDataAccessLayer.execute(TransactionalDataAccessLayer.java:47)
      at com.intel.aa.smoove.access.TestDataAccessCalibration.findCalibrationById(TestDataAccessCalibration.java:59)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
      at org.junit.runners.Suite.runChild(Suite.java:127)
      at org.junit.runners.Suite.runChild(Suite.java:26)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

"VM Thread" prio=10 tid=0x000000000a691800 nid=0x42d8 runnable 

"GC task thread#0 (ParallelGC)" prio=6 tid=0x00000000022cf000 nid=0x245c runnable 

"GC task thread#1 (ParallelGC)" prio=6 tid=0x00000000022d0800 nid=0x3efc runnable 

"GC task thread#2 (ParallelGC)" prio=6 tid=0x00000000022d2800 nid=0x4310 runnable 

"GC task thread#3 (ParallelGC)" prio=6 tid=0x00000000022d5000 nid=0x2248 runnable 

"VM Periodic Task Thread" prio=10 tid=0x000000000a711800 nid=0x1324 waiting on condition 

JNI global references: 205

Heap
PSYoungGen      total 279552K, used 160467K [0x00000007d5d00000, 0x00000007e7b00000, 0x0000000800000000)
  eden space 266240K, 56% used [0x00000007d5d00000,0x00000007df043de8,0x00000007e6100000)
  from space 13312K, 72% used [0x00000007e6e00000,0x00000007e7770ed8,0x00000007e7b00000)
  to   space 13312K, 0% used [0x00000007e6100000,0x00000007e6100000,0x00000007e6e00000)
ParOldGen       total 86016K, used 15300K [0x0000000781800000, 0x0000000786c00000, 0x00000007d5d00000)
  object space 86016K, 17% used [0x0000000781800000,0x00000007826f12c0,0x0000000786c00000)
PSPermGen       total 36352K, used 36317K [0x000000077c600000, 0x000000077e980000, 0x0000000781800000)
  object space 36352K, 99% used [0x000000077c600000,0x000000077e977478,0x000000077e980000)

最佳答案

解决方案是使用 Spring 事务管理完成向 Spring 的迁移,并删除所有自(hibernate)管理的事务。

关于java - 使用 Spring EntityManager,使用 DBCP 测试死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26957647/

相关文章:

java - 使用 DateFormat 类获取日期和日期字符串 - Android

java - 使用 Spring JPA 查询过滤数据

spring - @Value 没有被注入(inject)到其他包中

java - 如何以编程方式发现 Spring Boot 使用的 JPA 实现和 SQL 方言?

java - Hibernate:如何处理DAO中的Session以正确设置关联?

hibernate - JPA,Hibernate 我可以做复合主键,其中一个元素是外键@OneToMany?

java - ItemProcessor 的 Spring Batch 瓶颈

java - 为什么我得到包 javax.crypto 不存在

java - 无法解析方法 setEmptyView

java - Spring Batch Item Reader 只执行一次