Sitio de gran volumen con ADO.NET TransactionScope vs ExecuteCommand en NOLOCK, ¿LEER NO COMPROMETIDO directamente?

StackOverflow https://stackoverflow.com/questions/628004

Pregunta

Simplemente lea este interesante artículo de Omar en su blog Linq to SQL resuelve el punto muerto de la transacción y el problema de tiempo de espera de la consulta utilizando lecturas no confirmadas y al final Javed Hasan comenzó a discutir con él sobre su solución a la situación de nolock en un sitio de gran volumen.

Aquí, el problema que trata de resolver es que, desde el sentido de sql, necesitamos usar sentencias Select con NOLOCK o usar SET TRANSACTION LEVEL READ UNCOMMITTED, de lo contrario, las filas de alto volumen en DB se bloquearán y causarán errores. La tecnología utilizada por Omar es Linq2Sql, por lo que la pregunta es ¿cómo logramos esto en su código de acceso a datos C # para que no ocurra lo anterior?

Básicamente en la publicación, Omar llega a su solución trabajando y probando en sitios del mundo real y con herramientas como SqlProfiler, mientras que Javed Hasan llega a su solución con documentos de MSDN y la publicación de blog de Scott Hanselman, etc.

Omar sugiere usar lo siguiente

using (var db = new DropthingsDataContext2())
{
  db.Connection.Open();
  db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

  var user = db.aspnet_Users.First();
  var pages = user.Pages.ToList();
}

mientras que Javed Hasan sugiere

using (new TransactionScope(TransactionScopeOption.Required, 
  new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
 //Your db Operation
}

Estoy muy interesado en saber qué hacen ustedes sobre este tema en particular en un sitio de gran volumen como StatckOverflow, o ¿qué hicieron Jeff y sus muchachos al respecto?

Editar : después de leer la primera publicación, quiero señalar algunas cosas en la publicación de Omar.

  1. se encontró con un problema de conexión con su enfoque, pero lo resolvió, vea su publicación.
  2. lo más importante es que mencionó que intentó usar la forma de transacción ADO.NET e incluso intentó lo que Scott Hanselman escribió en su blog, pero no funciona para sitios de gran volumen, degrada bastante el rendimiento. Omar dijo que este " System.Transactions tiene una sobrecarga significativa. Nunca he podido usarlo en un sitio web de gran volumen sin hacer que la CPU funcione al 100% y Req / seg se reduzca a 1/10. Está hecho para aplicaciones empresariales, no para sitios web de gran volumen. & Quot;
¿Fue útil?

Solución

En primer lugar, evite las lecturas no confirmadas, pueden causar muchos problemas. Un enfoque mucho mejor es simplemente configurar la base de datos para aislamiento de instantánea . Esto es lo que hizo Jeff .

Jeff básicamente dijo: "bla bla bla, sé real, bla bla bla, teóricos de bases de datos, bla bla bla, READ UNCOMMITTED puede ser útil para aplicaciones de producción REALES que no necesitan consistencia de datos". Jeff no es un DBA, afortunadamente hay muchos DBA aquí en SO.

El problema con el enfoque de Omar es que puede filtrar conexiones con "leer sin confirmar". nivel de aislamiento en su grupo de conexiones que podría causar estragos en su sitio web. La declaración aleatoria de significado puede ejecutarse en lectura no confirmada

El enfoque Javed sería mucho mejor porque al desechar MS tiene la oportunidad de limpiar cosas en la conexión.

EDITAR Si tiene problemas de rendimiento con el enfoque de Javed, podría considerar implementar su propio administrador de transacciones.

Algunas cosas que probablemente quiera hacer:

  • Mantenga una pila de transacciones actuales
  • Confirma que estás en el hilo creador cuando se confirma una transacción
  • Restablece el aislamiento de la transacción a su estado anterior al deshacerse
  • Revertir al deshacerse si la transacción no se confirmó.
  • Soporta reversiones anidadas.

Otros consejos

Soy desarrollador de un equipo de herramientas en el grupo de SQL Server en Microsoft. Muchas aplicaciones no son muy sensibles a la coherencia de las transacciones, especialmente si escribes una aplicación que hace informes o algo en lo que ocasionalmente los datos inconsistentes no son el fin del mundo. Por supuesto, si escribe una solicitud financiera u otra cosa que tiene muy poca tolerancia a la inconsistencia de datos, probablemente desee explorar otras soluciones.

Si elijo usar lecturas no confirmadas, tengo blogueó una solución práctica usando métodos de extensión en C #.

{Mi reputación (pobre) me impide publicar comentarios, así que pongo esto como respuesta}

Si usa IsolationLevel a través de System.Transactions y crea un nuevo contexto de Linq dentro del bloque de transacciones, SQL Server termina intentando llamar a DTC para coordinar la transacción. Eso me sucedió y fue bastante inesperado.

Con respecto a las transacciones en .Net y el efecto secundario (de alguna manera sorprendente) del DTC, este documento Presentación de System.Transactions en .NET Framework 2.0 de Juval Lowy explica muy bien las cosas y sigue siendo totalmente válido (.Net4). Vale la pena leer. (También habría publicado un comentario ... si pudiera).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top