我的应用程序使用休眠 JPA 连接 postgres DB,如果我只有 1 个线程将数据写入 DB,则需要永远完成写入,然后我使用 10 个线程,这会导致 DB 出现死锁问题。JPA 不应该自动处理线程控制吗?
这是我的休眠配置:
应用程序上下文.xml:
<bean id="entityManagerFactory" class="javax.persistence.Persistence"
factory-method="createEntityManagerFactory" destroy-method="close" scope="singleton">
<constructor-arg value="${persistence_unit}" />
<constructor-arg>
<util:map>
<entry key="javax.persistence.jdbc.url" value="${db_url}" />
<entry key="javax.persistence.jdbc.user" value="${db_user}" />
<entry key="javax.persistence.jdbc.password" value="${db_password}" />
<!-- Connection provider properties.-->
<entry key="hibernate.c3p0.max_size" value="${hibernate_c3p0_max_size}" />
<entry key="hibernate.c3p0.min_size" value="${hibernate_c3p0_min_size}" />
<entry key="hibernate.c3p0.acquire_increment" value="${hibernate_c3p0_acquire_increment}" />
<entry key="hibernate.c3p0.idle_test_period" value="${hibernate_c3p0_idle_test_period}" />
<entry key="hibernate.c3p0.max_statements" value="${hibernate_c3p0_max_statements}" />
<entry key="hibernate.c3p0.timeout" value="${hibernate_c3p0_timeout}" />
</util:map>
</constructor-arg>
</bean>
操作-config.properties:
hibernate_c3p0_max_size=100
hibernate_c3p0_min_size=1
hibernate_c3p0_acquire_increment=1
hibernate_c3p0_idle_test_period=60
hibernate_c3p0_max_statements=0
hibernate_c3p0_timeout=30
hibernate_max_fetch_depth=3
hibernate_generate_statistics=false
使用多线程写入,出现以下错误:
2013-Feb-12 14:04:26.621 ERROR o.h.u.JDBCExceptionReporter o.h.u.JDBCExceptionReporter,101 Batch entry 0 insert into TAGS (name, tagtype, id) values ('2135daa6-6d88-43aa-9a7d-cc5ee5735893', '1', '10004') was aborted. Call getNextException to see the cause.
2013-Feb-12 14:04:26.621 WARN o.h.u.JDBCExceptionReporter o.h.u.JDBCExceptionReporter,100 SQL Error: 0, SQLState: 23505
2013-Feb-12 14:04:26.622 ERROR o.h.u.JDBCExceptionReporter o.h.u.JDBCExceptionReporter,101 ERROR: duplicate key value violates unique constraint "tags_name_key"
2013-Feb-12 14:04:26.627 ERROR o.h.e.d.AbstractFlushingEventListener o.h.e.d.AbstractFlushingEventListener,324 Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
...
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into TAGS (name, tagtype, id) values ('2135daa6-6d88-43aa-9a7d-cc5ee5735893', '1', '10004') was aborted. Call getNextException to see the cause.
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@412ad7b3 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Feb 12, 2013 2:05:13 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@412ad7b3 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@86fbfc2 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@60965de1 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@2fed9051 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@159dce6c