2011-05-28 23 views
7

Estoy usando TransactionScope para hacer algunas inserciones y actualizaciones por lotes. El problema es que obtengo excepciones de tiempo de espera en una operación de 30 minutos de duración incluso cuando establezco el tiempo de espera de TransactionScope en una hora.El tiempo de espera de TransactionScope se produce prematuramente?

También después de la excepción, inserta cantidades aparentemente aleatorias de los registros del lote. Por ejemplo, la última operación tenía 12440 insertos y después del tiempo de espera, se insertaron 7673 registros en la tabla.

El tiempo de espera de SqlConnection y SqlCommand se establece en int.MaxValue.

¿Qué estoy haciendo mal?

Aquí está mi código:

using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromHours(1))) 
{ 
     try 
     { 
       using (db = new DB()) 
       { 
       //operations here 
       } 
     } 
     catch (Exception ex) 
     { 
       throw new Exception("DB Error:\r\n\r\n" + ex.Message); 
     } 

     transaction.Complete(); 
} // <--- Exception here: Transaction aborted (Inner exception: Timeout) 
+1

una pregunta más grande (y posiblemente más importante) es "¿por qué unos pocos diez mil INSERTOS tardan tanto?" –

+0

¿Podría ser un * Tiempo de espera de comando * que está ocurriendo (y por lo tanto ser un arenque para un * Timeout de TransactionScope *)? Esto explicaría la "aleatoriedad", y teniendo en cuenta que los registros se insertan tan * muy * lentamente ... Veo que la pregunta dice "Valor_Max", pero sospecho ... que el problema no es el que parece. –

+0

@Mitch: se ha hecho un bye uno en una conexión muy lenta. De ahí el límite de tiempo de espera de una hora :) @pst: Insertar se hace en un bucle. Cada iteración establece CommandText y se ejecuta. Así que no está esperando el resultado de un gran SQL, dudo que sea un tiempo de espera de comando. También uso un DAL muy simple con solo SqlConnection y SqlCommand, no veo nada más que se agote el tiempo. Con mucho gusto verificaría cualquier otra cosa que puedas sugerir? – dstr

Respuesta

8

¿Su transacción falla después de 10 minutos? Si es así, probablemente esté presionando el Transaction Manager Maximum Timeout que está configurado en machine.config. Si recuerdo correctamente, si intenta establecer un tiempo de espera mayor que el valor máximo, se ignorará su configuración. Intente subir el valor en machine.config y vea si eso ayuda con su problema.

En términos de confirmaciones al azar, ¿configura Transaction Binding=Explicit Unbind en su cadena de conexión? El valor predeterminado es Transaction Binding=Implicit Unbind. De MSDN:

implícito Unbind hace que la conexión a desprenderse de la transacción cuando se extremos. Después de separar, las solicitudes adicionales en la conexión son realizadas en el modo de confirmación automática. La propiedad System.Transactions.Transaction.Current no se comprueba cuando se ejecutan las solicitudes mientras la transacción es activa. Después de que la transacción ha finalizado , las solicitudes adicionales son realizadas en modo de confirmación automática.

Básicamente, cuando los tiempos de transacción fuera todas las inserciones hasta ese momento se pondrá en marcha de nuevo, pero cualquier inserción adicional por hacer uso de la misma conexión se llevará a cabo en el modo de confirmación automática en la que se compromete de inmediato cada instrucción de inserción. Eso suena similar al escenario que está viendo (pero es difícil saberlo sin ver el código completo/repro).

2

que iba a ver si se puede utilizar el SqlBulkCopy Class. Debería ser mucho más rápido y podría eliminar la necesidad de un largo tiempo de espera.

Cuestiones relacionadas