2008-10-10 35 views
41

estoy recibiendo el siguiente error al intentar llamar a un procedimiento almacenado que contiene una instrucción SELECT:"La operación no es válida para el estado de la transacción" Alcance del error y la transacción

La operación no es válida para el estado de la transacción

Aquí está la estructura de mis llamadas:

public void MyAddUpdateMethod() 
{ 

    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
     using(SQLServer Sql = new SQLServer(this.m_connstring)) 
     { 
      //do my first add update statement 

      //do my call to the select statement sp 
      bool DoesRecordExist = this.SelectStatementCall(id) 
     } 
    } 
} 

public bool SelectStatementCall(System.Guid id) 
{ 
    using(SQLServer Sql = new SQLServer(this.m_connstring)) //breaks on this line 
    { 
     //create parameters 
     // 
    } 
} 

¿el problema es conmigo la creación de otra conectan ion a la misma base de datos dentro de la transacción?

Respuesta

41

Después de investigar un poco, parece que no puedo tener dos conexiones abiertas en la misma base de datos con el bloque TransactionScope. Necesitaba modificar mi código para tener este aspecto:

public void MyAddUpdateMethod() 
{ 
    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
     using(SQLServer Sql = new SQLServer(this.m_connstring)) 
     { 
      //do my first add update statement    
     } 

     //removed the method call from the first sql server using statement 
     bool DoesRecordExist = this.SelectStatementCall(id) 
    } 
} 

public bool SelectStatementCall(System.Guid id) 
{ 
    using(SQLServer Sql = new SQLServer(this.m_connstring)) 
    { 
     //create parameters 
    } 
} 
+0

Me encontré con la misma situación. Tuve que referirme a dos bases de datos diferentes dentro del mismo alcance de transacción. Gracias por el consejo. – rageit

+3

Buena captura, un lugar común para ver esto suceder es si tiene un marco de registro (nlog, log4net) que está escribiendo en el DB, ya que el marco de registro creará su propia conexión a la base de datos como su aplicación. – viggity

+0

¿Dónde encontraste esa información? –

1

He encontrado este error cuando mi transacción está anidada en otra. ¿Es posible que el procedimiento almacenado declare su propia transacción o que la función llamante declare una?

+0

que no tienen ningún código de transacción T-SQL en cualquier de mis procedimientos almacenados. En teoría, la transacción debe ser controlada por MyAddUpdateMethod() –

+0

+1 porque he recibido este error cuando el idioma de transacción en mi proceso almacenado era incorrecto, es decir, los recuentos de transacciones estaban en mal estado. – codeMonkey

7

también me encuentro con el mismo problema, he cambiado de espera de transacción a los 15 minutos y funciona. Espero que esto ayude.

TransactionOptions options = new TransactionOptions(); 
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; 
options.Timeout = new TimeSpan(0, 15, 0); 
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options)) 
{ 
    sp1(); 
    sp2(); 
    ... 

} 
+7

Sospecho que no es el tiempo de espera el que cambió el comportamiento sino el hecho de que ha cambiado el nivel de aislamiento de Serializable a ReadCommitted. –

5

Cuando me encontré con esta excepción, se produjo un InnerException "Tiempo de espera de transacción". Como esto fue durante una sesión de depuración, cuando detuve mi código durante algún tiempo dentro de TransactionScope, elegí ignorar este problema.

Cuando esta excepción específica con un tiempo de espera aparece en código desplegado, creo que la siguiente sección en el archivo .config que le ayudará a cabo:

<system.transactions> 
     <machineSettings maxTimeout="00:05:00" /> 
</system.transactions> 
Cuestiones relacionadas