Una de TransactionScope por favor!!!!

Buenos días a todos, no tenía pensado en escribir nada de este maravilloso elemento, pero estamos haciendo una pequeña refactorización de código porque algún DBA nos dijo que en nuestra aplicación teníamos un poco de contención con las transacciones y yo pensé “Transacciones?? Si prácticamente no las usamos”, infeliz de mí, luego hice una búsqueda sencilla por el código y aquí estoy quitando código y escribiendo sobre esto.

 

Lo que me he encontrado hasta la saciedad es esto

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
//Acción sobre base de datos
DoSomething.....
scope.Complete();
}

Dónde el DoSomething es un Insert, un Update, un Delete o un Select (sí, sí… se ven cosas que dan mucho miedito), a ver…

¿PARA QUÉ NECESITAS UNA TRANSACCIÓN?, es que parece que si un insert está dentro de una transacción mola más o debe ser algo parecido, pero lo único que hace es NADA, o dar un poco por saco en todo caso.

 

Otro caso gracioso es poner una transacción para una sentencia de selección, joe… esa es buenísima y la he visto demasiadas veces por desgracia, ahora imaginaos una select entre varias tablas de vuestra base de datos que sea pesada y que tenga un transactionscope con IsolationLevel a Serializable (uuuuuuuuuuuuhhh escalofríos me entran sólo de pensarlo).

 

Otro tema son los transactionscopes encadenados, para hacer justamente eso, una acción, esto encima tiene delito porque pones a trabajar al DTC en una transacción distribuida, os pongo un ejemplito de código que me he encotrado, para que veáis:

private void Metodo1()
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{ //Acción sobre base de datos
Metodo2();
scope.Complete()
}
}

private void Metodo2()
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{ //Acción sobre base de datos
DoSomething...
scope.Complete()
}
}

 

Conclusión

Los TransactionScope están para lo que están, no para abusar de ellos porque nos pueden poner en situación bastante perjudiciales para el rendimiento de nuestra máquina, y nos pueden a llevar a bloqueos en base de datos sin quererlo. Así que se tienen que usar con cabeza y vuelvo a repetir, UNA ÚNICA OPERACIÓN EN BASE DE DATOS NO NECESITA UN TRANSACTIONSCOPE.

 

Perdonad por el tono del post, es que estoy muy cabreado con esto, que estoy aquí pico y pala quitando transactionscopes que me salen por las orejillas, intentaré escribir algún post con algún ejemplo más tangible.

 

Saludicos.

12 comentarios en “Una de TransactionScope por favor!!!!”

  1. Vaya hombre, pues yo pensaba que el TransactionScope se utilizaba precisamente para esto 😀

    ¿Podrías explicar entonces en qué casos se usa el TransactionScope?

    ¿Cómo se soluciona entonces el problema de las transacciones encadenadas? (sin pasar la sesión explícitamente entre llamadas)

    Un saludo

  2. Hola,

    Evidentemente el uso excesivo no es una buena opción. Por mi experiencia personal puedo decir que las clases del System.Transaction son una magnifíca opción para el uso de transacciones ligeras a través del Lightweight Transaction Manager; de hecho publiqué un articulo en dotnetmania (creo que por el año 2006, no se el num exacto, tendria que mirar) que hablaba sobre todas las posibilidades que éste ofrecía.

    Un muy buen recurso es el Whitepaper de Juval Lowy Introducing System.Transactions in the Microsoft .NET Framework version 2.0 que podeis encontrar aqui: http://www.microsoft.com/downloads/details.aspx?FamilyId=AAC3D722-444C-4E27-8B2E-C6157ED16B15&displaylang=en

    En fín, te animo a que sigas escribiendo sobre el tema ;-))

    Un saludo

  3. Intento contestaros

    @ A. P.: Pues el transactionScope se usa para unir en una transacción “múltiples” acciones, no una acción que es el caso que ocupa. Porque da exactamente igual, que tengas una transacción o no, el resultado va a ser el mismo, y sinceramente creo que no es bueno abusar.
    Lo de las transacciones encadenas no es que sea malo, es solo que puede pasar que desconozcamos que si se encadenan más de un transactionscope se escala al DTC.

    @José Miguel Torres: Si estoy totalmente de acuerdo, creo que no he dicho que el System.Transaction sea malo, si lo he dejado entrever creo que ha sido un desliz, pero lo que si que digo es que un abuso no puede ser bueno en ningún caso y os aseguro que el código que estaba cambiando es porque se estaba haciendo un abuso.
    Lo de Juval Lowy, he escuchado su nombrecico varias veces… y me aconsejaron un libro suyo de WCF, pero miraré, miraré… y sí creo que es un tema del que escribir, seguiré investigando.

    Gracias por vuestros comentarios.

  4. Mario,

    100% recomendable el libro de Juval Lowy. Echale un vistazo a su la Web de su empresa (www.iDesign.net). Tambien te recomiendo el libro sobre WCF de Hadi Hariri de Krasis Press, en español.

    Un saludo!!!

  5. Mario

    Sería muy recomendable entender una tecnología antes de escribir sobre ella. Lo que acabas de afirmar es un error en todos los sentidos y es un error que muchos novatos comenten. TODA operación de base de datos se realiza dentro de una transacción. Si tu no creas un explícitamente, se creará una de manera implícita. Esta creación implícita a veces incluso es peor en rendimiento.

    Y cuando digo TODA operación, es tanto SELECTS, como actualizaciones.

    Por último, usando TransactionScope tienes la posibilidad de intervenir y votar en transacciones anidadas. Y muchas veces tu no sabes quien llama tu código.

    Si tienes deadlocks, tu problema no son las transacciones.

  6. @Anonimo:

    Lo que Mario pretende comentar es el uso inadecuado del administrador de recursos, no del concepto, en este caso LTM. En cuanto a las tranascciones implicitias el tema es algo más complicado y no es generico a todas las base de datos aunque entiendo que estas hablando de SQL Server. En cuanto a rendimiento de una “transaccion implicita peor que una explicita” no entiendo bien que quieres decir. Las transacciones no han sido concebidas bajo criterios de opitmización de renidmiento sino de bajo los conceptos de atomicidad, durabilidad, aislamiento y de consistencia de las operaciones que se ejecutan bajo su contexto.

    Por ulimo, si tienes deadlock, puede ser que sea problemas de las transacciones ( de su aislamiento o granularidad del bloqueo) pero también puede ser por otros motivos.

    Saludos,,,

  7. A ver Anónimo, eres un poquito tonto verdad?? Que tendrán que ver las pollas con las cebollas me pregunto yo!!, es decir, que tendrá que ver lo que se está hablando, creación de transaciones LTM, promoción a distribuídas, con que la base de datos use transacciones implícitas, esto no es más que un detalle técnico que nada tiene que ver con el concepto de transaccion ACID para un conjunto de operaciones lanzadas desde cliente…

  8. Segundo anónimo, eso de tonto creo que te equivocas. TransactionScope no pone a trabajar el DTC a menos que la cadena de conexión sea distinta. Con lo cual aunque uses TransactionScope, no será distribuida.

    Segundo, ya que tanto hacéis énfasis en ACID, no usar transacciones, podría provocar errores en la interpretación de datos en función del Isolation Level definido.

    Por último, tanto SQL SErver, como ORacle y otras bases de datos tienen el concepto de transacción implícita.

    Pero vamos, que me llamen tonto. Hagan lo que quieran. Allá ustedes.

  9. Bueno, me estabais tentando de jugar a la ‘mascarada’ y postear como anónimo, ¡parece divertido! 🙂

    De todos modos, me gusta eso de que mis comentarios vayan vinculados a mi nombre, quizá por egocentrismo 😛

    A ver, tengamos las cosas claras: TransactionScope puede poner a trabajar al DTC (o a el Oracle MTS, o al coordinador de transacciones distribuidas de turno) tanto de modo explicito como implicito. Por ello, “Anonimo 1”, he de decir que, lamentablemente, te recomiendo que revises tus fuentes…

    En el caso del enlistamiento en transacciones distribuidas implicito, depende del proveedor. Por ejemplo, en Oracle se da la curiosidad de que SIEMPRE que creas una transaccion dentro de un TransactionScope, automática e implicitamente escala d distribuida, y por tanto, pasa por el DTC. Si quereis una referencia, podeis consultar en tantos sitios de internet (es algo muy conocido), pero para muestra, un botón:
    http://download.oracle.com/docs/html/B28089_01/featADO20.htm

    El el caso de trabajar contra SQL Server, si el TransactionScope incluye multiples statements automáticamente lo enlista en una transaccion distribuida.

    Esto no es ciencia de cohetes, y es muy conocido. Por eso me sorprende tanta polémica. Todos podemos errar, yo el primero. Pero “Anonimo 1”, quizá te precipitaste al decir que Mario no conoce el tema, porque yo no he encontrado ningun fallo en su artículo. Quizá yo también me equivoque, quien sabe 🙂

  10. Bufff… Anónimo1, no se por donde empezar a responder, sobre todo despues de tu último comentario, en el que demuestras que no sabes de lo que estás hablando como bien te ha respondido Pablo, de todas formas creo que con lo que ha dicho no hace falta acotar más… no vaya ser que seas un TROL y quieras protagonismo..
    P.D: Mario, sigue posteando anda 🙂
    Saludos
    Unai

  11. @preguntoncojonero -> El uso de transactionscope no siempre implica usar DTC, de hecho sólo se escala a DTC en ciertas ocasiones, o bien cuando se usan dos cadenas de conexión distintas, o bien cuándo se usa un proveedor que no soporte LTM, como era el caso de Oracle, que era el caso de este post.
    Si es con ADO.NET usalas siempre que realmente lo necesites y además como bien dices el escalará a DTC cuando sea necesario.
    Lo único importante es sólo usalo cuando lo necesites, para hacer una acción en base de datos NO es necesario.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *