tablas tabla saving requieren recreación realizado que puedo permitted permitir permite not modificar los impedir guardar enmascaramiento datos columna changes cambios sql stored-procedures sql-server-2008-r2 server-error

tabla - saving changes is not permitted sql server



"Esta SqlTransaction se ha completado; ya no se puede usar. "... ¿error de configuración? (7)

He estado trabajando en esto durante aproximadamente un día y medio, y busqué numerosos blogs y artículos de ayuda en la Web. Encontré varias preguntas sobre SO relacionadas con este error, pero no creí que se aplicaran a mi situación (o en algunos casos, desafortunadamente, no pude entenderlas lo suficiente como para implementarlas: P). No estoy seguro de poder describir esto lo suficiente como para ayudar ... pero aquí va:

Tenemos una aplicación .NET para rastrear nuestros recursos. Hay una función de exportación para copiar un recurso al sistema de seguimiento de tiempo y al sistema de facturación; esto accede a un procedimiento almacenado que enlaza con las bases de datos de tiempo y facturación.

Recientemente cambié la base de datos del sistema de facturación a un nuevo servidor (servidor original: Server 2003 SP2, SQL 2005, servidor nuevo: Server 2008 R2, SQL 2008 R2). Tengo una configuración de servidor vinculado que apunta a las bases de datos de 2008. Actualicé el procedimiento almacenado para apuntar al servidor 2008, y luego recibí un error sobre MSDTC y RPC (http://www.safnet.com/writing/tech/archives/2007/06/server_myserver.html). Activaba ''rpc / rpc out'' en el servidor vinculado y establecí MSDTC para permitir el acceso a la red (algo como esto: http://www.sqlwebpedia.com/content/msdtc-troubleshooting ).

Ahora obtengo lo anterior, cuando intento ejecutar la función de exportación: "Este SqlTransaction se ha completado, ya no se puede usar". Lo que me parece extraño es que cuando solo ejecuto el procedimiento almacenado (desde SSMS), dice que se completa con éxito.

¿Alguien ha visto esto antes? ¿Me he perdido algo en la configuración? Sigo repasando las mismas páginas, y lo único que encontré fue que no reinicié después de realizar los cambios de MSDTC (mencionado aquí: http://social.msdn.microsoft.com/forums/en-US/adodotnetdataproviders/thread/7172223f-acbe-4472-8cdf-feec80fd2e64/ ).

Puedo publicar parte o todo el procedimiento almacenado, si me ayudaría ... por favor avíseme.


Aquí hay una forma de detectar la transacción Zombie

SqlTransaction trans = connection.BeginTransaction(); //some db calls here if (trans.Connection != null) //Detecting zombie transaction { trans.Commit(); }

Descompilando la clase SqlTransaction, verá lo siguiente

public SqlConnection Connection { get { if (this.IsZombied) return (SqlConnection) null; return this._connection; } }

Noto que si la conexión está cerrada, la transOP se convertirá en zombie, por lo tanto no puede Commit . Para mi caso, es porque tengo el Commit() dentro de un bloque finally , mientras que la conexión estaba en el bloque try . Esta disposición hace que la conexión se elimine y se recoja la basura. La solución fue poner Commit dentro del bloque try lugar.


Creo que este mensaje de error se debe a una "transacción zombie".

Busque posibles áreas donde la transacción se está cometiendo dos veces (o revertida dos veces, o revertida y comprometida, etc.). ¿El código .Net compromete la transacción después de que el SP ya la haya comprometido? ¿El código .Net lo retrotrae al encontrar un error, y luego intenta volver a tirarlo en una cláusula catch (o finally)?

Es posible que nunca se llegue a un error en el servidor anterior y, por lo tanto, el código "doble retrotracción" defectuoso nunca se golpeó. Tal vez ahora tenga una situación en la que haya algún error de configuración en el nuevo servidor, y ahora el código defectuoso se está recibiendo mediante el manejo de excepciones.

¿Puedes depurar en el código de error? ¿Tienes un rastro de pila?


En mi caso, el problema era que una de las consultas incluidas en la transacción generaba una excepción, y aunque la excepción se manejó con "gracia", aún así logró deshacer la transacción completa.

Mi pseudo-código fue como:

var transaction = connection.BeginTransaction(); for(all the lines in a file) { try{ InsertLineInTable(); // INSERT statement might fail and throw an exception } catch { // notify the user about the error on line x and continue } } // Commit and Rollback will fail if one of the queries // in InsertLineInTable threw an exception if(CheckTableForErrors()) { transaction.Commit(); } else { transaction.Rollback(); }


Lo tuve recientemente después de refactorizar en un nuevo administrador de conexión. Una nueva rutina aceptaba una transacción por lo que se podía ejecutar como parte de un lote, el problema era con un bloque de uso:

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null) { using (transaction.Connection) { using (transaction) { return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure); } } }

Parece que el uso externo estaba cerrando la conexión subyacente, por lo que cualquier intento de comprometer o revertir la transacción arrojó el mensaje "This SqlTransaction has completed; it is no longer usable."

Eliminé los usos añadidos una prueba de cobertura y el problema desapareció.

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null) { return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure); }

Compruebe si hay algo que pueda estar cerrando la conexión mientras se encuentra dentro del contexto de una transacción.


Recientemente me encontré con una situación similar. Para depurar en cualquier versión de VS IDE, abra excepciones desde Debug (Ctrl + D, E) - marque todas las casillas de verificación con la columna "Lanzada" y ejecute la aplicación en modo de depuración. Me he dado cuenta de que una de las tablas no se importó correctamente en la nueva base de datos, por lo que la Excepción Sql interna estaba matando la conexión, lo que da como resultado este error.

La esencia de la historia es: si el código de trabajo anterior devuelve este error en una nueva base de datos, podría tratarse de un problema en el esquema de la base de datos que falta, realice la sugerencia de depuración anterior,

Hope It Help, HydTechie


También compruebe si hay procesos de larga ejecución ejecutados desde su aplicación .NET contra el DB. Por ejemplo, puede estar llamando a un procedimiento almacenado o una consulta que no tiene suficiente tiempo para terminar y que se puede mostrar en sus registros como:

  • Tiempo de espera de ejecución caducado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde.

    • Esta SqlTransaction se ha completado; ya no es utilizable

Compruebe la configuración de tiempo de espera del comando Intente ejecutar un seguimiento (generador de perfiles) y vea qué está sucediendo en el lado de la base de datos ...


Tengo el mismo problema. Este error se produce debido a la agrupación de conexiones. Cuando existen dos o más usuarios acceden al sistema, la agrupación de conexiones reutiliza una conexión y la transacción también. Si el primer usuario ejecuta commit ou rollback, la transacción ya no se puede usar.