2009-04-24 64 views
8

Tengo un código muy simple usando ADO.NET que arroja la excepción ORA-08177. No estoy seguro de qué pasa con esto. Estoy intentando esto en una máquina de Windows Vista que tiene instalado el cliente Oracle de 32 bits. Mi opción de compilación para Visual Studio está configurada en la plataforma x86.ORA-08177: no se puede serializar el acceso para esta transacción

Dim connection As OracleConnection = Nothing 
Dim transaction As OracleTransaction = Nothing 

Try 
    connection = New OracleConnection("Data Source=ora10;User Id=userid;Password=passwd;") 
    connection.Open() 

    transaction = connection.BeginTransaction(IsolationLevel.Serializable) 

    Dim inputStream As New System.IO.FileStream("Dummy.xls", IO.FileMode.Open) 
    Dim fileLength As Integer = CType(inputStream.Length, Integer) 
    Dim input(fileLength) As Byte 

    Try 
     inputStream.Read(input, 0, fileLength) 
    Finally 
     If inputStream IsNot Nothing Then inputStream.Close() 
    End Try 

    Dim deleteSql As String = "DELETE FROM TABLE1 WHERE Version = 'v1' " 

    Dim cmd As New OracleCommand(deleteSql, connection, transaction) 
    cmd.ExecuteNonQuery() 

    Dim insertQuery As String = "INSERT INTO TABLE1 (VERSION, DATA) VALUES (:VERSION, :DATA) " 
    Dim insertCmd As OracleCommand = New OracleCommand(insertQuery, connection, transaction) 
    insertCmd.Parameters.Clear() 
    insertCmd.CommandType = Data.CommandType.Text 
    insertCmd.Parameters.AddWithValue(":VERSION", "v1") 
    insertCmd.Parameters.AddWithValue(":DATA", input) 

    insertCmd.ExecuteNonQuery() 
    transaction.Commit() 

Catch 
    If transaction IsNot Nothing Then transaction.Rollback() 
    Throw 
Finally 
    If transaction IsNot Nothing Then transaction.Dispose() 
    If connection IsNot Nothing AndAlso connection.State <> ConnectionState.Closed Then connection.Close() 
End Try 

Lo importante a destacar: (No estoy seguro de si están conectados) pero no se enfrentan a este problema si se desinstala últimas actualizaciones de las ventanas de mi máquina.

¿Alguien ha enfrentado esto o tiene alguna pista sobre lo que está pasando aquí?

Editar: -

tengo algunos progresos en donde he descubierto que este problema se produce sólo cuando tenemos blob tipo de columna en cuestión. para columnas simples funciona bien.

Otros detalles (no estoy seguro si eso hace la diferencia)

estoy trabajando en 64 bits de Windows Vista máquina de negocio. He instalado un cliente de Oracle de 32 bits para Windows Vista (ya que el cliente de Oracle de 64 bits no funciona en Vista). Estoy compilando mi proyecto para un x86 (entorno de 32 bits) en Visual Studio. Y esta es una aplicación de consola y sé que nadie más está accediendo a la base de datos en este momento. entonces no puede haber múltiples transacciones.

Y no veo este problema si desinstalo la última actualización de Windows. (KB963027, KB967190, KB959426, KB960225, KB960803, KB952004, KB956572, KB958687, KB958690, KB958481, KB958483, KB943729)

+0

Podría usted por favor enviar un archivo de rastreo para que la sesión? – Quassnoi

+0

¿Nivel de aislamiento serializable? Me pregunto si es realmente necesario ... –

+0

¿Qué versión de Oracle? – DCookie

Respuesta

19

Está utilizando una transacción serializable que espera por alguna otra operación de bloqueo a la misma mesa ROLLBACK.

Si esta otra transacción no se revierte sino que se compromete, obtendrá este error.

El escenario parece ser de la siguiente manera:

  1. Alice abre la sesión del navegador que pide DELETE FROM TABLE1 WHERE Version = 'v1'

    • Bob abre la sesión que llama DELETE FROM TABLE1 WHERE Version = 'v1' después Alice hicieron pero antes de que ella comprometida.

    Bob 's espera de transacción desde Alice cerraron las filas con Version = 'v1'

    • Alice compromete su transacción

    • Bob' s transacción falla con Cannot serialize access

Para evitar esto, establezca TRANSACTION ISOLATION LEVEL-READ COMMITTED:

transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted) 

En este caso, Bob 'consulta s será reeditado después Alice comete sus cambios, como si Bob' transacción s se inició después de Alice 's uno fue cometido.

actualización

Podría por favor enviar un rastro de su conexión?

Para ello, emita este comando justo después de la conexión:

(New OracleCommand("ALTER SESSION SET SQL_TRACE=TRUE", connection, transaction)).ExecuteNonQuery(); 

, a continuación, busque en $ORACLE_HOME\admin\udump para un archivo *.trc fresca

+0

Gracias por su respuesta. Me enfrento a este problema cuando estoy ejecutando esto usando una aplicación de consola y sé que no hay nadie más que yo golpeando esa base de datos. – MOZILLA

+0

¿Podría verificar si este problema persiste cuando cambia el nivel de aislamiento de la transacción? – Quassnoi

+0

Sí, esta solución funciona: resolvió mi problema – DNKROZ

Cuestiones relacionadas