将ARRAY传递给存储过程时出现死锁

在将ARRAY发送到stord proc时,我们正在获得java级死锁。 我正在附加线程转储。

Found one Java-level deadlock: ============================= "http-bio-8080-exec-11": waiting to lock monitor 0x00000000406fb2d8 (object 0x00000000fea1b130, a oracle.jdbc.driver.T4CConnection), which is held by "http-bio-8080-exec-4" "http-bio-8080-exec-4": waiting to lock monitor 0x00000000407d6038 (object 0x00000000fe78b680, a oracle.jdbc.driver.T4CConnection), which is held by "http-bio-8080-exec-11" Java stack information for the threads listed above: =================================================== "http-bio-8080-exec-11": at oracle.sql.TypeDescriptor.getName(TypeDescriptor.java:682) - waiting to lock  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.oracore.OracleTypeCOLLECTION.isInHierarchyOf(OracleTypeCOLLECTION.java:149) at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2063) at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3579) at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685) - locked  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714) - locked  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376) at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1066) at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1014) at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1064) at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144) 

如何避免这种僵局。

代码:类扩展org.springframework.jdbc.object.StoredProcedure

 Map result; Map hashMap = new HashMap(); hashMap.put(SOME_IDS_PARAM, getJdbcTemplate().execute(new ConnectionCallback() { @Override public Object doInConnection(Connection con) throws SQLException, DataAccessException { Connection connection = new SimpleNativeJdbcExtractor().getNativeConnection(con); ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(schema + ".ARRAY_OF_NUMBER" , connection); return new oracle.sql.ARRAY(descriptor, connection, someIds); } })); result = super.execute(hashMap); 

即使我尝试过这种方法:

 OracleConnection connection = null; DataSource datasource = null; Map result; try { datasource = getJdbcTemplate().getDataSource(); connection = (OracleConnection) DataSourceUtils.getConnection(datasource); synchronized (connection) { Map hashMap = new HashMap(); hashMap.put(SOME_IDS_PARAM, getArrayOfNumberValue(someIds, schema, connection)); result = super.execute(hashMap); } } finally { if (null != connection) { DataSourceUtils.releaseConnection(connection, datasource); } } 

数组:

 public ARRAY getArrayOfNumberValue(Integer[] array, String schema, OracleConnection connection) throws DataAccessResourceFailureException { String arrayOfNumberTypeName = schema + ARRAY_OF_NUMBER; ARRAY oracleArray = null; ArrayDescriptor descriptor = null; try { descriptor = (ArrayDescriptor) connection.getDescriptor(arrayOfNumberTypeName); if (null == descriptor) { descriptor = new ArrayDescriptor(arrayOfNumberTypeName, connection); connection.putDescriptor(arrayOfNumberTypeName, descriptor); } oracleArray = new ARRAY(descriptor, connection, array); } catch (SQLException ex) { throw new DataAccessResourceFailureException("SQLException " + "encountered while attempting to retrieve Oracle ARRAY", ex); } return oracleArray; } 

我怀疑,当我从“connection =(OracleConnection)DataSourceUtils.getConnection(datasource);”检查连接时。 它将为您提供逻辑连接但底层它将使用“T4Connection”,但它正在释放它。 并再次寻找相同的连接。

  java.lang.Thread.State: BLOCKED (on object monitor) at oracle.sql.TypeDescriptor.getName(TypeDescriptor.java:682) - waiting to lock  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.oracore.OracleTypeCOLLECTION.isInHierarchyOf(OracleTypeCOLLECTION.java:149) at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2063) at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3579) at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685) - locked  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714) - locked  (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376) at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1066) at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1014) at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1064) at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144) at com.intuit.platform.integration.sdx.da.procedures.subscription.serviceSubscription.LookupRealmSubscriptions.execute(LookupRealmSubscriptions.java:55) - locked  (a oracle.jdbc.driver.LogicalConnection) at com.intuit.platform.integration.sdx.da.ServiceSubscriptionDAOImpl.getRealmServiceSubscriptions(ServiceSubscriptionDAOImpl.java:153) at com.intuit.platform.integration.sdx.ws.beans.ServiceSubscriptionResourceBean.filterRealmIds(ServiceSubscriptionResourceBean.java:84) 

ARRAY中的连接与正在执行存储过程的连接不同。 您可以看到这一点,因为等待锁定的T4CConnection(堆栈跟踪的第3行)与先前锁定的IF具有不同的IF。

使用如何获取Spring JDBC中的当前Connection对象以获取当前连接,然后使用https://stackoverflow.com/a/7879073/1395668将其向下转换为Oracle连接中的答案。 然后,您应该能够为当前连接创建有效的ARRAY,并且您不应该遇到死锁。