tutorial java mysql jdbc mybatis

java - tutorial - APARATO DEADLOCK Creando hilos de emergencia para tareas pendientes no asignadas



mybatis spring (3)

Estoy usando mysql con mybatis y saludo este error en nuestro servidor en vivo

com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6538f8f2 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

No entiendo por qué viene este error, ¿esto se debe a mi configuración de C3P0? Mis ajustes de C3P0 son así

---- inicio actualizado -----

A continuación se muestra mi configuración spring-servlet.xml.

He actualizado el bean de datos como

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" p:driverClass="com.mysql.jdbc.Driver" p:jdbcUrl="jdbc:mysql://localhost/jdb" p:user="root" p:password="root" p:acquireIncrement="10" p:idleConnectionTestPeriod="60" p:maxPoolSize="100" p:maxStatements="0" p:minPoolSize="10" p:initialPoolSize="10" p:statementCacheNumDeferredCloseThreads="1" /> <!-- Declare a transaction manager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="datasource" /> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="datasource" /> </bean> <!-- scan for mappers and will automatically scan the whole classpath for xmls --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> <property name="basePackage" value="com.mycom.myproject.db.mybatis.dao" /> </bean>

y de mi clase Dao llamo método mapeador como

myDao.updateRecords()

Este es mi método de clase de servicio.

@Override public List<UserDetailedBean> selectAllUsersDetail(long groupId, List<Long> ids) { List<UserDetailedBean> usersDetailList = null; try { usersDetailList = userDao.selectAllUsersDetail(groupId, ids); } catch (Exception e) { e.printStackTrace(); } return usersDetailList; }

En la clase Dao acabo de inyectar el mapeador.

@Resource private UserMapper userMapper; @Override public List<UserDetailedBean> selectAllUsersDetail(long groupId, List<Long> ids) { return userMapper.selectAllUsersDetail(groupId,ids); }

--- fin actualizado ------

por favor, hágamelo saber si se requiere cualquier otra información.

Esta es la traza completa de la pila.

[ WARN] 2013-01-08 20:13:39 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@70497e11 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! [ WARN] 2013-01-08 20:13:39 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@70497e11 -- APPARENT DEADLOCK!!! Complete Status: Managed Threads: 3 Active Threads: 3 Active Tasks: com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2e81b8c5 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@4689a55d (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@76c7a0d8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) Pending Tasks: com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2c1101d4 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@108f1be6 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2370a188 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@377cf9e5 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@6dfa45d8 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@49ffa050 com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2d760a24 Pool thread stack traces: Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main] java.net.SocketInputStream.socketRead0(Native Method) java.net.SocketInputStream.read(SocketInputStream.java:150) java.net.SocketInputStream.read(SocketInputStream.java:121) com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114) com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161) com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189) com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2549) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002) com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557) com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.java:4984) com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.java:51) com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.java:4962) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.java:185) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:62) com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.java:67) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:368) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:310) com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:1999) com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main] java.net.SocketInputStream.socketRead0(Native Method) java.net.SocketInputStream.read(SocketInputStream.java:150) java.net.SocketInputStream.read(SocketInputStream.java:121) com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114) com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161) com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189) com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2549) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002) com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557) com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.java:4984) com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.java:51) com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.java:4962) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.java:185) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:62) com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.java:67) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:368) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:310) com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:1999) com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main] java.net.SocketInputStream.socketRead0(Native Method) java.net.SocketInputStream.read(SocketInputStream.java:150) java.net.SocketInputStream.read(SocketInputStream.java:121) com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114) com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161) com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189) com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2549) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002) com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618) com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557) com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.java:4984) com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.java:51) com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.java:4962) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.java:185) com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:62) com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.java:67) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:368) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:310) com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:1999) com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

---Actualizado----

cuando agregué p: statementCacheNumDeferredCloseThreads = "1" al datasouce bean, aparece el siguiente error

Error creating bean with name ''sqlSessionFactory'' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Cannot resolve reference to bean ''datasource'' while setting bean property ''dataSource''; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''datasource'' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property ''statementCacheNumDeferredCloseThreads'' of bean class [com.mchange.v2.c3p0.ComboPooledDataSource]: Bean property ''statementCacheNumDeferredCloseThreads'' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?


Desde http://www.mchange.com/projects/c3p0/#other_ds_configuration

numHelperThreads y maxAdministrativeTaskTime ayudan a configurar el comportamiento de los grupos de subprocesos DataSource. Por defecto, cada fuente de datos tiene solo tres hilos auxiliares asociados. Si el rendimiento parece arrastrar bajo una carga pesada, o si observa a través de JMX o la inspección directa de un PooledDataSource, que el número de "tareas pendientes" suele ser mayor que cero, intente aumentar numHelperThreads. maxAdministrativeTaskTime puede ser útil para los usuarios que experimentan tareas que se cuelgan indefinidamente y mensajes de "APPARENT DEADLOCK". (Vea el Apéndice A para más información).

maxAdministrativeTaskTime Valor predeterminado: 0 segundos antes de que el grupo de subprocesos de c3p0 intente interrumpir una tarea aparentemente bloqueada. Rara vez útil. Muchas de las funciones de c3p0 no son ejecutadas por subprocesos de clientes, sino asincrónicamente por un conjunto de subprocesos interno. La asincronía de c3p0 mejora el rendimiento del cliente directamente y minimiza el tiempo durante el cual se mantienen los bloqueos críticos al garantizar que las operaciones jdbc lentas se realicen en subprocesos sin retención de bloqueo. Sin embargo, si algunas de estas tareas se "cuelgan", es decir, no tienen éxito ni fallan con una excepción durante un período de tiempo prolongado, el grupo de subprocesos de c3p0 puede agotarse y las tareas administrativas se pueden respaldar. Si las tareas son simplemente lentas, la mejor manera de resolver el problema es aumentar el número de subprocesos, a través de numHelperThreads . Pero si las tareas a veces se cuelgan indefinidamente, puede usar este parámetro para forzar una llamada al método interrupt () del hilo de tareas si una tarea supera un límite de tiempo establecido. [c3p0 eventualmente se recuperará de las tareas bloqueadas de todos modos al señalar un "APPARENT DEADLOCK" (lo verá como una advertencia en los registros), reemplazando los subprocesos de tareas del grupo de subprocesos e interrumpiendo los subprocesos originales. Pero dejar que la agrupación entre en APLICENT DEADLOCK y luego recuperarse significa que durante algunos períodos, el rendimiento de c3p0 se verá afectado. Por lo tanto, si está viendo estos mensajes, puede serle útil aumentar numHelperThreads y establecer maxAdministrativeTaskTime . maxAdministrativeTaskTime debe ser lo suficientemente grande como para que cualquier intento razonable de adquirir una conexión de la base de datos, probar una conexión, o dos destruir una conexión, tenga éxito o falle dentro del tiempo establecido. Cero (el valor predeterminado) significa que las tareas nunca se interrumpen, lo cual es la mejor y más segura política en la mayoría de las circunstancias. Si las tareas son solo lentas, asigna más hilos. Si las tareas se cuelgan para siempre, intente averiguar por qué, y tal vez la configuración de maxAdministrativeTaskTime puede ayudar mientras tanto.

The default is 3 for numHelperThreads , increase this to 8-10 setting maxAdministrativeTaskTime will help


En mi caso, la causa fue muy poca memoria para la aplicación. El DB utilizado fue H2 o SQLite (ambos están en uso en esta aplicación).

El primer síntoma fue estas líneas de registro WARN como se informó anteriormente:

12006925 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|33af2d37]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6d3a9c65 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 12016284 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|3d98d1b]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@44565f94 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 12051847 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|5703a6aa]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@c9f37e2 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 12085128 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|4e50d42b]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6f1927b7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 12085128 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|78fa7f84]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@22c22b50 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 12172644 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|e8e88fa]-AdminTaskTimer] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@745a644f -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

Seguido de excepciones después de mucho tiempo, incluida la revelación:

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

El problema era reproducible. Dando a la aplicación más memoria (-Xmx8G) lo arregló.


Por favor revise los siguientes pasos para solucionar el problema:

  1. Aumente p:maxStatements en ComboPooledDataSource.

  2. Establezca p:maxStatements en 0. Por ejemplo, en Firebird este hack funciona ComboPooledDataSource.

  3. Asegúrese de cerrar SqlSession en su aplicación. Prestar más atención a la ejecución intensiva de operaciones de base de datos. En mi versión del controlador JSBC de mySql: las conexiones de mysql-connector-java 5.1.8 se cierran automáticamente cuando el objeto se recolecta como basura. Por lo tanto, en su caso, las conexiones no deberían filtrarse si no utiliza la base de datos de forma intensiva. Sin embargo, debe asegurarse de estar cerca de myBatis SqlSession que envuelve la conexión jdbc a la base de datos.

  4. También en consecuencia, la conexión JDBC3 y la agrupación de sentencias puede intentar establecer statementCacheNumDeferredCloseThreads en 1 en la configuración c3p0.