2010-03-22 20 views
13

Duplicar posible:
Entity Framework with NOLOCKcómo forzar Marco de la entidad de no bloquear la base de datos

estoy usando EF4 y .Net 4 a cargar algunos XML de un archivo en una base de datos .

Tengo una clase que rodea el ObjectContext y tiene métodos que agregan los objetos agrupados del archivo XML a las distintas EntityCollections que representan mis tablas.

Cada archivo XML contiene alrededor de 200,000 objetos en promedio, la clase contenedora crea el ObjectContext en la construcción y almacena la referencia en una variable de clase privada local que luego es utilizada por los métodos.

Cuando he terminado de crear las entidades que llaman:

entities.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); 

Esto crea una transacción en el servidor que es según el diseño ADO.NET Entity Framework. Sin embargo, esta transacción bloquea por completo mi DB incluso en tablas a las que no se agrega.

he intentado varias cosas para tratar de conseguir alrededor de esto, como aislamientos guardar los cambios en un TransactionScope así:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress, 
     new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted })) 
     { 
      entities.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); 

      transaction.Complete(); 
     } 

También he intentado crear el TransactionScope antes de crear el ObjectContext en un intento de influir en el subyacente transacción que se utiliza durante SaveChanges.

Idealmente, me gustaría cargar varios archivos a la vez, pero esto será imposible si el DB está bloqueado durante los cambios de guardado.

¿Alguien conoce una solución a este problema? ¿Hay alguna posibilidad de forzar a EntityFramework a no usar una transacción?

Gracias por cualquier ayuda con anticipación.

James

+0

Creo que el problema aquí es que está utilizando TransactionScopeOption.Supress. Intenta usar Requerido. –

Respuesta

13

Sólo para poner esto a la cama im va a publicar lo que fue mi solución.

básicamente que estaba viendo esto desde el extremo equivocado del problema, una transacción se utiliza cuando se llama a SaveChanges() pero todavía se puede leer la base de datos mediante el uso de un método como este:

private static FrameEntities GetEntities() 
    { 
     FrameEntities entities = new FrameEntities(); 
     entities.ExecuteStoreCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"); 
     return entities; 
    } 

Ajusta el aislamiento nivel antes de intentar leer.

Esto normalmente no se recomienda, ya que puede leer "sucio" de datos parciales, pero por lo que estoy haciendo bien.

+3

Esto no funciona. Establecer el nivel de aislamiento de transacción por sí solo no tendrá ningún efecto. En realidad, necesita estar ejecutándose dentro de una transacción para que tenga algún efecto. La documentación de MSDN para READ UNCOMMITTED declara que las transacciones que se ejecutan en el nivel LEER SIN COMPROMISO no emiten bloqueos compartidos. Esto implica que debe estar ejecutándose dentro de una transacción para obtener el beneficio. (tomado de msdn.microsoft.com/en-gb/library/ms173763.aspx).Su enfoque puede ser menos intrusivo, pero no logrará nada si no utiliza una transacción. –

Cuestiones relacionadas