Oracle Streams AQ. session.getQueue выдает исключение AQOracleSQLException: исчерпанный результирующий набор

#spring #stream #pooling #oracle-aq

#spring #поток #объединение в пул #oracle-aq

Вопрос:

Используя Oracle Streams AQ в многопоточной среде с несколькими приложениями, я получил AQOracleSQLException : Исчерпанный результирующий набор примерно через 10 минут работы только в одном потоке.

 oracle.AQ.AQOracleSQLException: Exhausted Resultset
        at oracle.AQ.AQOracleSession.getQueue(AQOracleSession.java:751)
        at au.com.xxx.queue.OracleQueue$$anonfun$2.apply(OracleQueue.scala:53)
  

AQOracleSession Объединяется через Spring следующим образом:

 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/MessageManagerDB"/>
</bean>

<bean id="aqSessionFactory" class="au.com.xxx.queue.AQSessionFactory">
    <constructor-arg ref="dataSource"/>
</bean>

<bean id="aqSessionTarget" factory-bean="aqSessionFactory" 
    factory-method="createAQSession" scope="prototype"/>

<bean id="aqSessionPoolTargetSource" 
    class="org.springframework.aop.target.CommonsPoolTargetSource">
    <property name="targetBeanName" value="aqSessionTarget"/>
    <property name="maxSize" value="25"/>
</bean>

<bean id="aqSession" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource" ref="aqSessionPoolTargetSource"/>
</bean>
  

С использованием заводского метода createAQSession (в Scala):

 def createAQSession = {
  val wasConnection = dataSource.getConnection.asInstanceOf[WSJdbcConnection]
  val connection = WSCallHelper.getNativeConnection(wasConnection).asInstanceOf[Connection]
  SessionWithConnection(AQDriverManager.createAQSession(connection), connection)
  // SessionWithConnection is just a case class akin to 
  // Tuple2[AQOracleSession, Connection]
}
  

Исключение было выдано из последней строки этого блока:

 def sessionAndConnection = {
  applicationContext.getBean("aqSession").asInstanceOf[SessionWithConnectionI]
}

def write(category: String, relatedId: Option[String], payload: String): Array[Byte] = {
  val (session, conn) = {
    val sc = sessionAndConnection
    (sc.session, sc.connection)
  }
  val queueDef = dao.queueForWriting(category, relatedId).map{_.name}
  val queue = queueDef.map{name => session.getQueue("QUSR", name)}
  

Очевидно, я напрямую не обрабатываю ResultSet используемый внутри AQOracleSession .

Я использую Connection связанный с Session , но это произойдет позже в том же методе, и поэтому здесь не может быть ошибки:

 val clob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION)
  

Возможно ли, что конфигурация пула неверна и в одном сеансе выполнялись некоторые параллельные операции? В других журналах вообще не было ничего необычного.

Ответ №1:

Это дефект драйвера v10, который я использовал по ошибке. драйвер СУБД v11 не имеет этой проблемы.