2011-02-08 24 views
5

Tengo una ventana de informe que muestra los resultados devueltos por un procedimiento almacenado potencialmente oráculo de larga ejecución. Mi problema es que cuando el usuario cierra la ventana, la conexión a Oracle permanece abierta y el informe que se ejecuta durante mucho tiempo no se cancela.Forzar el cierre de una conexión oráculo en C#

La única manera de cerrar la conexión abierta es que los DBA los eliminen manualmente o que el usuario salga de la aplicación completa.

He intentado llamar al Close en la conexión de un hilo diferente, pero parece que se bloquea continuamente. También traté de deshacer una transacción, pero esto muestra el mismo problema.

Me preocupa que la única solución sea ejecutar la consulta en un proceso diferente (¿o quizás en el dominio de la aplicación?).

Es probable que me falta algo obvio, cualquier ayuda sería muy apreciada.

LEA

Esta pregunta no se trata de envolver mi conexión en un comunicado using. Se trata de cómo forzar una conexión oráculo que está ejecutando una consulta para cerrar.

Ejemplo:

  • iniciar un hilo de ejecutar una consulta
  • Stash el objeto de conexión en algún lugar
  • de llamadas de cerca el objeto de conexión

    public void Go() 
    { 
        OracleConnection connection; 
        var queryThread = new Thread(
         () => 
          { 
           using (connection = OpenOracleConnection()) 
           { 
            // execute stored proc that takes 45 mins 
            // raise an event with the data set we load 
           } 
          }); 
    
        Thread.Sleep(3000); // give it time to be useless 
    
        var closeThread = new Thread(
         () => 
          { 
           connection.Close(); 
          }); 
        closeThread.Start(); 
    } 
    

El problema es que esto no cierra la conexión, en cambio, la llamada a connection.C lose() bloques esperando a que se ejecute el procedimiento.

+0

Qué ADO.NET proveedor de Oracle está utilizando?(El Microsoft provisto de uno no es compatible con el procesamiento asincrónico, por lo que si es ese, es posible que necesite escribir código para conectarse en otra conexión y matar el proceso ofensivo). – driis

+0

Es el proveedor Oracle.DataAccess que viene con 11.2.0. – jonnii

+1

No es una pregunta bien hecha. Obviamente, tendrá que abortar la consulta primero. No obtendrá una respuesta hasta que explique cómo puso en marcha el accidente de tren, "ventana de informe" no tiene sentido. Código postal –

Respuesta

2

Hm, no puedo ver nada en la API para cancelar/cancelar una consulta en curso. Técnicamente debería ser posible, con una segunda sesión con privilegios completos, identificar la sesión que desea abortar y emitir el comando kill session en esa sesión. Esperaría que tu sesión original rescatara con algún tipo de excepción, pero nunca la probé.

Here se explica cómo matar una sesión.

Here se responde cómo obtener la identificación de la sesión. Podría encontrarlo antes de comenzar la consulta de larga ejecución, entonces sería muy fácil eliminar exactamente esa sesión de una segunda conexión.

hacernos saber si funciona;)

+0

Buena idea, voy a correr esto más allá de los DBA, a ver si van a ir por eso. Creo que significaría dar a las credenciales de llamadas la capacidad de alterar el sistema, que podría no funcionar. – jonnii

+0

puede usar un usuario diferente para hacer la sesión de matar, no tiene que ser la misma cuenta ... – flq

+1

He batido esto y funciona muy bien, esto me apuntó en la dirección correcta. Estoy haciendo 'seleccionar sid, número de serie de v $ sesión donde audsid = sys_context ('userenv', 'sessionid')' seguido de una sesión 'Alterar sistema kill (sid, session) immediate' si el usuario necesita abortar el consulta. – jonnii

0

Como con cualquier proveedor en .NET puede llamar Dispose

using(var conn = /* your connection */) { 
    // do your stuff 

    conn.Close(); 
} // this will automatically call .Dispose() 

Así que eso es todo lo que necesita hacer.

+0

¿Cómo puedo llamar cerrar o eliminar cuando el hilo que abre la conexión y que está ejecutando la consulta está bloqueado durante 45 minutos? – jonnii

+0

Debo admitir que mi experiencia con una base de datos Oracle es limitada, pero puedo decirle que no es normal que una consulta se bloquee durante 45 minutos. Ayudaría si publicaras cómo estás abriendo la conexión, deberías poder cerrar la conexión, no puedes significa que es tu código. –

+0

No todas las consultas tardan 45 minutos, la mayoría se ejecutan en cuestión de segundos, pero esto requiere que las personas proporcionen parámetros para reducir el conjunto de resultados. Desafortunadamente, no siempre proporcionan los correctos. – jonnii

1

para ver qué/quién está bloqueando que:

select s1.username || '@' || s1.machine 
    || ' (SID=' || s1.sid || ') is blocking ' 
    || s2.username || '@' || s2.machine || ' (SID=' || s2.sid || ') ' AS status 
    from v$lock l1, v$session s1, v$lock l2, v$session s2 
    where s1.sid=l1.sid and s2.sid=l2.sid 
    and l1.BLOCK=1 and l2.request > 0 
    and l1.id1 = l2.id1 
    and l2.id2 = l2.id2; 
Cuestiones relacionadas