visual tools studio odp net framework for data .net database oracle

.net - studio - oracle data tools



ActualizaciĆ³n de Oracle se bloquea (6)

Estoy teniendo problemas con una actualización de Oracle. La llamada a ExecuteNonQuery se bloquea indefinidamente.

El código:

using (OracleCommand cmd = new OracleCommand(dbData.SqlCommandStr, conn)) { foreach (string colName in dbData.Values.Keys) cmd.Parameters.Add(colName, dbData.Values[colName]); cmd.CommandTimeout = txTimeout; int nRowsAffected = cmd.ExecuteNonQuery(); }

CommandTimeout se establece en 5 y los parámetros se configuran en pequeños valores enteros.

La consulta:

UPDATE "BEN"."TABLE03" SET "COLUMN03"=:1,"COLUMN04"=:2 WHERE COLUMN05 > 0

La consulta se ejecuta rápidamente desde sqlplus, y normalmente se ejecuta rápidamente desde mi código, pero de vez en cuando se cuelga para siempre.

Ejecuté una consulta en v $ locked_object, y hay un registro que hace referencia a esta tabla, pero creo que esa es la actualización que no se está completando.

Hay dos cosas que me gustaría saber: ¿qué podría causar que se cuelgue la actualización?

Más importante aún, ¿por qué no se lanza una excepción aquí? Esperaría que la llamada aguarde cinco segundos y luego agote el tiempo.


Cuando una actualización simple se cuelga, a menudo significa que estás bloqueado por otra sesión. Oracle no permitirá que más de una transacción actualice una fila. Hasta que una transacción no haya comprometido o revertido sus modificaciones, bloqueará las filas que haya actualizado o eliminado. Esto significa que otra sesión tendrá que esperar si quieren modificar las mismas filas.

Debes SELECCIONAR ... PARA ACTUALIZAR NOWAIT antes de ACTUALIZAR si no quieres colgar indefinidamente.


Estaba teniendo un problema similar que estaba siendo causado por un comando Sql que no se había comprometido. Supongo que el programa se colgó en medio de uno en algún momento.

Aquí es cómo resolví mi problema:

Primero, abra SqlPlus y haga un compromiso para solucionar el problema.

A continuación, cambie el código para confirmar la transacción o deshacer si se produce una excepción. Eso evitará que el problema vuelva a ocurrir.

Podrías cambiar tu código a algo como esto:

using (OracleTransaction transaction = conn.BeginTransaction()) { using (OracleCommand cmd = new OracleCommand(dbData.SqlCommandStr, conn)) { foreach (string colName in dbData.Values.Keys) cmd.Parameters.Add(colName, dbData.Values[colName]); cmd.CommandTimeout = txTimeout; try { int nRowsAffected = cmd.ExecuteNonQuery(); transaction.Commit(); } catch { transaction.Rollback(); } } }


Estoy topando con esto debido a su rango de página en los resultados de búsqueda.

En mi caso, fue porque había ejecutado una consulta en SqlPlus, pero olvidé comprometerla. En este caso, fue como dijo Vincent: la fila se bloqueó en otra sesión.

Comprometerse con la actualización de SqlPlus resolvió el problema.


Me he encontrado con este problema con frecuencia y con algo más que consultas de actualización (especialmente "INSERT INTO ... SELECT FROM" consultas). Esto está en Oracle 9i.

Encontré la solución, así que decidí encontrar este tema SO relacionado: En la cadena de conexiones, establezca:

Pooling=False

en la cadena de conexión. Una cadena de conexión completa y funcional podría verse así:

DATA SOURCE=k19.MYDOMAIN.com/plldb;PERSIST SECURITY INFO=True;Pooling=False;USER ID=IT;Password=SECRET

Advertencias: Establecer la agrupación en falso requerirá que su consulta asegure una nueva conexión cada vez que se ejecute. Las consultas que se ejecutan con mucha frecuencia pueden experimentar una disminución en el rendimiento en comparación con lo que tendrían si ODP.NET fuera confiable. Teniendo en cuenta el problema, correr un poco más lento es mucho mejor que ahorcar.


Puede ver qué evento está esperando su sesión consultando V $ SESSION_WAIT (después de identificar el SID de la sesión, probablemente mirando V $ SESSION). Si el evento es algo así como "en cola", está esperando un bloqueo retenido por otra sesión, lo que parece ser una explicación probable en este caso.


parece que la base de datos está esperando una confirmación / restitución, por lo que bloquea la fila. Sugeriría agregar

int nRowsAffected = cmd.ExecuteNonQuery(); cmd.Commit();