While sending ARRAY to the stord proc we are getting java level dead locks. I am attaching the thread dump.
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 <0x00000000fea1b130> (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 <0x00000000fe78b680> (a oracle.jdbc.driver.T4CConnection)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714)
- locked <0x00000000fe78b680> (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)
How to avoid these kind of deadlocks.
Code :
Class extends 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);
Even I tried with this approach:
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);
}
}
Array :
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;
}
I suspect that, when i check out the connection from "connection = (OracleConnection) DataSourceUtils.getConnection(datasource);". It will give you the logical connection but underlying it will make use of the "T4Connection" but it is releasing it. And again looking for the same connection.
java.lang.Thread.State: BLOCKED (on object monitor)
at oracle.sql.TypeDescriptor.getName(TypeDescriptor.java:682)
- waiting to lock <0x00000000c1356fc8> (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 <0x00000000c14b34f0> (a oracle.jdbc.driver.T4CConnection)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714)
- locked <0x00000000c14b34f0> (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 <0x00000000fbd00bc0> (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)