<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comentarios en: Transacciones y modos de aislamiento en SQL Server y .NET</title>
	<atom:link href="http://www.programandoamedianoche.com/2009/04/transacciones-y-modos-de-aislamiento-en-sql-server-y-adonet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.programandoamedianoche.com/2009/04/transacciones-y-modos-de-aislamiento-en-sql-server-y-adonet/</link>
	<description>Blog de Scientia® Soluciones Informaticas</description>
	<lastBuildDate>Thu, 29 Jul 2010 19:46:04 -0300</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>Por: Dario Krapp</title>
		<link>http://www.programandoamedianoche.com/2009/04/transacciones-y-modos-de-aislamiento-en-sql-server-y-adonet/comment-page-1/#comment-109</link>
		<dc:creator>Dario Krapp</dc:creator>
		<pubDate>Thu, 14 Jan 2010 21:05:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.programandoamedianoche.com/?p=278#comment-109</guid>
		<description>Muchas gracias por consultar y perdón por la demora, voy a intentar ir contestando por punto.

1. Sin hacer uso de transacciones, considerando las operaciones sobre la base de datos a nivel de instrucción; con ADO.NET, ¿como implementarías el bloqueo pesimista?.

Alguna vez y hace unos cuantos años tuve la oportunidad de conocer un proyecto hecho en VB6.0 con SQLServer 7.0 donde los bloqueos eran manejados completamente a mano y eran pesimistas, esto se lograba de la siguiente manera;
Las tablas poseian un registro extra denominado UserId (Id de usuario) donde cuando un usuario tomaba un registro su Id se grababa en ese campo y se pasaba a NULL cuando el mismo era liberado. Este esquema de
funcionamiento permitía manejar los bloqueos ya que cuando un usuario quería acceder a un registro, la aplicación podía saber si el mismo se encontraba bloqueado o no leyendo el campo UserId. Este modo de funcionamiento
añadía a los problemas clásicos de escalabilidad que poseen los bloqueos pesimistas nuevos problemas propios de la implementación, ya que si un usuario abandonaba la aplicación inesperadamente el registro quedaba bloquedo y aunque es
posible encontrar métodos para evitar este problema, mi punto de vista es que no es para nada recomendable utilizar bloqueos.    

2. Si por ejemplo empleo un DataAdapter (o TableAdapter) para realizar operaciones sobre la base de datos, ¿qué tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.

Un DataAdapter es un objeto que te va a permitir leer datos de un source y moverlos a memoria en un DataSet y efectuar también el paso contrario, o sea moverlos nuevamente al source luego de haberlos modificado en memoria, el método
Fill va a transferir los datos del source a memoria y el método Update va a leer los datos de memoria y los va a transferir nuevamente al source, por lo que el funcionamiento por defecto es el comportamiento &quot;el último gana&quot;, 
para probarlo podés crear una tabla simple en SQL Server, te dejo un ejemplo:
 

CREATE TABLE [dbo].[Datos1](
	[ID] [int] NOT NULL,
	[Numero] [int] NOT NULL,
	[Descripcion] [nvarchar](50) NOT NULL
) ON [PRIMARY]


y utilizar el siguiente código

        SqlConnection SqlCn = new SqlConnection(WebConfigurationManager.ConnectionStrings[&quot;Cn1&quot;].ConnectionString);
        SqlCn.Open();

        //DataAdapter
        SqlDataAdapter SqlDa = new SqlDataAdapter(&quot;SELECT * FROM Datos1&quot;, SqlCn);
        SqlDa.AcceptChangesDuringUpdate = true; 
 
        //Comando para actualización
        SqlCommand command = new SqlCommand(&quot;UPDATE Datos1 SET Descripcion = @Descripcion WHERE ID = @ID&quot;, SqlCn);

        //Parámetro Descripcion
        SqlParameter parameterDesc = command.Parameters.Add(&quot;@Descripcion&quot;, SqlDbType.NVarChar, 50);
        parameterDesc.SourceVersion = DataRowVersion.Current;
        parameterDesc.SourceColumn = &quot;Descripcion&quot;;

        //Parámetro ID
        SqlParameter parameterID = command.Parameters.Add(&quot;@ID&quot;, SqlDbType.Int);
        parameterID.SourceVersion = DataRowVersion.Original;
        parameterID.SourceColumn = &quot;ID&quot;;
        SqlDa.UpdateCommand = command;

        //Lectura de datos
        DataSet DataSetD1 = new DataSet();
        SqlDa.Fill(DataSetD1, &quot;TableDatos1&quot;);

        //Actualización en memoria
        foreach (DataRow DtRow in DataSetD1.Tables[0].Rows)
             DtRow[&quot;Descripcion&quot;] = DtRow[&quot;Descripcion&quot;] + &quot;Z&quot;;

        //Actualización en la base de datos
        SqlDa.Update(DataSetD1.Tables[&quot;TableDatos1&quot;]);

Donde básicamente se modifica el valor del campo Descripcion para todos los registros, si ponés un break point en la última sentencia &quot;SqlDa.Update(DataSetD1.Tables[&quot;TableDatos1&quot;]);&quot; y antes que se ejecute vas a un query analizer
y ejecutás lo siguiente:

	update Datos1 set Descripcion = Descripcion + &#039;i&#039;

antes de ejecutar la sentencia SqlDa.Update(DataSetD1.Tables[&quot;TableDatos1&quot;]); desde VS vas a ver que todos los registros poseen una &quot;i&quot; al final del campo Descripción, pero si luego presionas F5 en VS y ejecutás la sentencia
SqlDa.Update(DataSetD1.Tables[&quot;TableDatos1&quot;]); vas a notar que el cambio hecho desde el query analizer se ha perdido, ya que el update ha tomado los valores de memoria del DataSet (que aún no tenian el caracter i agregado) y los ha transferido al SQL, 
si haciendo la misma prueba borrás un registro desde el Query Analizer, vas a notar que se produce un error en la sentencia SqlDa.Update(DataSetD1.Tables[&quot;TableDatos1&quot;]); ya que no podrá actualizar registros que han sido eliminados externamente, en este caso te quedarán
algunos registros modificados (previos al error) o otros no (los sucesivos al error).


3. Si por el contrario realizo las operaciones con un objeto de tipo OleDbCommand, en un escenario conectado, ¿que tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.

De esto podrás pasarme un poco de código para entender como sería el caso.

4. ¿Como puedo implementar el bloqueo de tipo &quot;el último gana&quot;?

Este tipo de funcionamiento es el más sencillo de utilizar ya que podés leer la información necesaria de la base de datos, cortar la conexión, modificar la informacíon en forma desconectada y 
reenviar las modificaciones al servidor de base de datos en una nueva conexion (en una transaccion si hay varias tablas involucradas). En este esquema, si dos usuarios leen la misma información el último en grabar es quien
preservará sus cambios. 
Fuera de los puntos anteriores, para una aplicación actual y sin utilizar frameworks de entidades y esas cosas que estan tan de moda actualmente, yo particularmente pensaría en dos enfoques posibles, el enfoque &quot;el último gana&quot; y el enfoque &quot;optimista&quot;, 
dejando las transacciones para los casos donde haya varias tablas involucradas en una misma entidad. El enfoque &quot;el último gana&quot; es como te comentaba previamente mientras que para el enfoque optimista, podés incluir una columna extra con un numero de versión, 
al momento de actualizar los datos leidos previamente deberías verificar que el numero de versíon actual sea el mismo que leistes previamente, en caso afirmativo podrás modificar los datos incrementando el numero de version de la columna, en caso negativo deberás tomar alguna acción ya que la información ha sido
modificada externamente. Otra opción es en lugar de utilizar una columna version, emplear una columna datestamp para comparar contra fechas.        

5. Cuando se emplean transacciones, ¿los niveles de aislamiento definen el tipo de bloqueo?

Si, para que el motor de base de datos pueda asegurarte el nivel de aislamiento que le estás pidiendo, el mismo deberá efectuar un tipo de bloqueo determinado, por lo que el tipo de bloqueo dependerá del nivel de aislamiento solicitado.

La verdad esq tengo un poco de &quot;empanada mental&quot; con estos estos conceptos. A ver si me lo puedes aclarar un poco. 

Yo creo que hay dos cosas distintas; 
La primera es que cuando hay varias tablas involucradas a modificar en una misma operación de base de datos deben utilizarse transacciones y el nivel de aislamiento definirá que bloqueos realizará el motor de base de datos en dicha operación y eso es lo que intenta comentar el articulo.
La segunda es qué tipo de bloqueo se debe utilizar en una aplicación para que un usuario no modifique los datos que otro esta modificando paralelamente, creo si no entendí mal que es sobre este tipo de bloqueos sobre los cuales estás interesado, y según mi punto de vista, las opciones son &quot;el último gana&quot; o el enfoque &quot;optimista&quot;. 

Espero que estas repuestas te hayan servido

Saludos!</description>
		<content:encoded><![CDATA[<p>Muchas gracias por consultar y perdón por la demora, voy a intentar ir contestando por punto.</p>
<p>1. Sin hacer uso de transacciones, considerando las operaciones sobre la base de datos a nivel de instrucción; con ADO.NET, ¿como implementarías el bloqueo pesimista?.</p>
<p>Alguna vez y hace unos cuantos años tuve la oportunidad de conocer un proyecto hecho en VB6.0 con SQLServer 7.0 donde los bloqueos eran manejados completamente a mano y eran pesimistas, esto se lograba de la siguiente manera;<br />
Las tablas poseian un registro extra denominado UserId (Id de usuario) donde cuando un usuario tomaba un registro su Id se grababa en ese campo y se pasaba a NULL cuando el mismo era liberado. Este esquema de<br />
funcionamiento permitía manejar los bloqueos ya que cuando un usuario quería acceder a un registro, la aplicación podía saber si el mismo se encontraba bloqueado o no leyendo el campo UserId. Este modo de funcionamiento<br />
añadía a los problemas clásicos de escalabilidad que poseen los bloqueos pesimistas nuevos problemas propios de la implementación, ya que si un usuario abandonaba la aplicación inesperadamente el registro quedaba bloquedo y aunque es<br />
posible encontrar métodos para evitar este problema, mi punto de vista es que no es para nada recomendable utilizar bloqueos.    </p>
<p>2. Si por ejemplo empleo un DataAdapter (o TableAdapter) para realizar operaciones sobre la base de datos, ¿qué tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.</p>
<p>Un DataAdapter es un objeto que te va a permitir leer datos de un source y moverlos a memoria en un DataSet y efectuar también el paso contrario, o sea moverlos nuevamente al source luego de haberlos modificado en memoria, el método<br />
Fill va a transferir los datos del source a memoria y el método Update va a leer los datos de memoria y los va a transferir nuevamente al source, por lo que el funcionamiento por defecto es el comportamiento &#8220;el último gana&#8221;,<br />
para probarlo podés crear una tabla simple en SQL Server, te dejo un ejemplo:</p>
<p>CREATE TABLE [dbo].[Datos1](<br />
	[ID] [int] NOT NULL,<br />
	[Numero] [int] NOT NULL,<br />
	[Descripcion] [nvarchar](50) NOT NULL<br />
) ON [PRIMARY]</p>
<p>y utilizar el siguiente código</p>
<p>        SqlConnection SqlCn = new SqlConnection(WebConfigurationManager.ConnectionStrings["Cn1"].ConnectionString);<br />
        SqlCn.Open();</p>
<p>        //DataAdapter<br />
        SqlDataAdapter SqlDa = new SqlDataAdapter(&#8220;SELECT * FROM Datos1&#8243;, SqlCn);<br />
        SqlDa.AcceptChangesDuringUpdate = true; </p>
<p>        //Comando para actualización<br />
        SqlCommand command = new SqlCommand(&#8220;UPDATE Datos1 SET Descripcion = @Descripcion WHERE ID = @ID&#8221;, SqlCn);</p>
<p>        //Parámetro Descripcion<br />
        SqlParameter parameterDesc = command.Parameters.Add(&#8220;@Descripcion&#8221;, SqlDbType.NVarChar, 50);<br />
        parameterDesc.SourceVersion = DataRowVersion.Current;<br />
        parameterDesc.SourceColumn = &#8220;Descripcion&#8221;;</p>
<p>        //Parámetro ID<br />
        SqlParameter parameterID = command.Parameters.Add(&#8220;@ID&#8221;, SqlDbType.Int);<br />
        parameterID.SourceVersion = DataRowVersion.Original;<br />
        parameterID.SourceColumn = &#8220;ID&#8221;;<br />
        SqlDa.UpdateCommand = command;</p>
<p>        //Lectura de datos<br />
        DataSet DataSetD1 = new DataSet();<br />
        SqlDa.Fill(DataSetD1, &#8220;TableDatos1&#8243;);</p>
<p>        //Actualización en memoria<br />
        foreach (DataRow DtRow in DataSetD1.Tables[0].Rows)<br />
             DtRow["Descripcion"] = DtRow["Descripcion"] + &#8220;Z&#8221;;</p>
<p>        //Actualización en la base de datos<br />
        SqlDa.Update(DataSetD1.Tables["TableDatos1"]);</p>
<p>Donde básicamente se modifica el valor del campo Descripcion para todos los registros, si ponés un break point en la última sentencia &#8220;SqlDa.Update(DataSetD1.Tables["TableDatos1"]);&#8221; y antes que se ejecute vas a un query analizer<br />
y ejecutás lo siguiente:</p>
<p>	update Datos1 set Descripcion = Descripcion + &#8216;i&#8217;</p>
<p>antes de ejecutar la sentencia SqlDa.Update(DataSetD1.Tables["TableDatos1"]); desde VS vas a ver que todos los registros poseen una &#8220;i&#8221; al final del campo Descripción, pero si luego presionas F5 en VS y ejecutás la sentencia<br />
SqlDa.Update(DataSetD1.Tables["TableDatos1"]); vas a notar que el cambio hecho desde el query analizer se ha perdido, ya que el update ha tomado los valores de memoria del DataSet (que aún no tenian el caracter i agregado) y los ha transferido al SQL,<br />
si haciendo la misma prueba borrás un registro desde el Query Analizer, vas a notar que se produce un error en la sentencia SqlDa.Update(DataSetD1.Tables["TableDatos1"]); ya que no podrá actualizar registros que han sido eliminados externamente, en este caso te quedarán<br />
algunos registros modificados (previos al error) o otros no (los sucesivos al error).</p>
<p>3. Si por el contrario realizo las operaciones con un objeto de tipo OleDbCommand, en un escenario conectado, ¿que tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.</p>
<p>De esto podrás pasarme un poco de código para entender como sería el caso.</p>
<p>4. ¿Como puedo implementar el bloqueo de tipo &#8220;el último gana&#8221;?</p>
<p>Este tipo de funcionamiento es el más sencillo de utilizar ya que podés leer la información necesaria de la base de datos, cortar la conexión, modificar la informacíon en forma desconectada y<br />
reenviar las modificaciones al servidor de base de datos en una nueva conexion (en una transaccion si hay varias tablas involucradas). En este esquema, si dos usuarios leen la misma información el último en grabar es quien<br />
preservará sus cambios.<br />
Fuera de los puntos anteriores, para una aplicación actual y sin utilizar frameworks de entidades y esas cosas que estan tan de moda actualmente, yo particularmente pensaría en dos enfoques posibles, el enfoque &#8220;el último gana&#8221; y el enfoque &#8220;optimista&#8221;,<br />
dejando las transacciones para los casos donde haya varias tablas involucradas en una misma entidad. El enfoque &#8220;el último gana&#8221; es como te comentaba previamente mientras que para el enfoque optimista, podés incluir una columna extra con un numero de versión,<br />
al momento de actualizar los datos leidos previamente deberías verificar que el numero de versíon actual sea el mismo que leistes previamente, en caso afirmativo podrás modificar los datos incrementando el numero de version de la columna, en caso negativo deberás tomar alguna acción ya que la información ha sido<br />
modificada externamente. Otra opción es en lugar de utilizar una columna version, emplear una columna datestamp para comparar contra fechas.        </p>
<p>5. Cuando se emplean transacciones, ¿los niveles de aislamiento definen el tipo de bloqueo?</p>
<p>Si, para que el motor de base de datos pueda asegurarte el nivel de aislamiento que le estás pidiendo, el mismo deberá efectuar un tipo de bloqueo determinado, por lo que el tipo de bloqueo dependerá del nivel de aislamiento solicitado.</p>
<p>La verdad esq tengo un poco de &#8220;empanada mental&#8221; con estos estos conceptos. A ver si me lo puedes aclarar un poco. </p>
<p>Yo creo que hay dos cosas distintas;<br />
La primera es que cuando hay varias tablas involucradas a modificar en una misma operación de base de datos deben utilizarse transacciones y el nivel de aislamiento definirá que bloqueos realizará el motor de base de datos en dicha operación y eso es lo que intenta comentar el articulo.<br />
La segunda es qué tipo de bloqueo se debe utilizar en una aplicación para que un usuario no modifique los datos que otro esta modificando paralelamente, creo si no entendí mal que es sobre este tipo de bloqueos sobre los cuales estás interesado, y según mi punto de vista, las opciones son &#8220;el último gana&#8221; o el enfoque &#8220;optimista&#8221;. </p>
<p>Espero que estas repuestas te hayan servido</p>
<p>Saludos!
<div class="ratingblock ">
<div style="display: none">VN:F [1.7.3_972]</div>
<div id="comment_rater_109" class="ratecmm">
<div class="starsbar">
<div class="gdouter" align="left">
<div id="gdr_vote_c109" style="width: 60px;" class="gdinner"></div>
<div id="gdr_stars_c109" class="gdsr_rating_as"><a id="gdsrX109X5X0XcXcomment_rater_109Xcomment_loader_109" title="5 out of 5" class="s5" rel="nofollow"></a><a id="gdsrX109X4X0XcXcomment_rater_109Xcomment_loader_109" title="4 out of 5" class="s4" rel="nofollow"></a><a id="gdsrX109X3X0XcXcomment_rater_109Xcomment_loader_109" title="3 out of 5" class="s3" rel="nofollow"></a><a id="gdsrX109X2X0XcXcomment_rater_109Xcomment_loader_109" title="2 out of 5" class="s2" rel="nofollow"></a><a id="gdsrX109X1X0XcXcomment_rater_109Xcomment_loader_109" title="1 out of 5" class="s1" rel="nofollow"></a></div>
</div>
</div>
</div>
<div id="comment_loader_109" style="display: none; width:60px;" class="ratingloadercomment">
<div class="loader flower " style="height: 12px">
<div class="loaderinner">aguarde un momento...</div>
</div>
</div>
<div id="gdr_text_c109" class=" comment">Rating: 5.0/<strong>5</strong> (1 voto cast)</div>
</div>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Alex_TS</title>
		<link>http://www.programandoamedianoche.com/2009/04/transacciones-y-modos-de-aislamiento-en-sql-server-y-adonet/comment-page-1/#comment-108</link>
		<dc:creator>Alex_TS</dc:creator>
		<pubDate>Fri, 08 Jan 2010 03:24:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.programandoamedianoche.com/?p=278#comment-108</guid>
		<description>Buen artículo!, lo has explicado con bastante calidad. 

Lo único que te recomendaría es que pusieras un fondo claro bajo el texto, pero el contenido mola. 

Al respecto del tema que has tratado en este artículo, tengo ciertas dudas, son las siguientes:

1. Sin hacer uso de transacciones, considerando las operaciones sobre la base de datos a nivel de instrucción; con ADO.NET, ¿como implementarías el bloqueo pesimista?.

2. Si por ejemplo empleo un DataAdapter (o TableAdapter) para realizar operaciones sobre la base de datos, ¿qué tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.

3. Si por el contrario realizo las operaciones con un objeto de tipo OleDbCommand, en un escenario conectado, ¿que tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.

4. ¿Como puedo implementar el bloqueo de tipo &quot;el último gana&quot;?

5. Cuando se emplean transacciones, ¿los niveles de aislamiento definen el tipo de bloqueo?

La verdad esq tengo un poco de &quot;empanada mental&quot; con estos estos conceptos. A ver si me lo puedes aclarar un poco. 

Gracias y saludos!</description>
		<content:encoded><![CDATA[<p>Buen artículo!, lo has explicado con bastante calidad. </p>
<p>Lo único que te recomendaría es que pusieras un fondo claro bajo el texto, pero el contenido mola. </p>
<p>Al respecto del tema que has tratado en este artículo, tengo ciertas dudas, son las siguientes:</p>
<p>1. Sin hacer uso de transacciones, considerando las operaciones sobre la base de datos a nivel de instrucción; con ADO.NET, ¿como implementarías el bloqueo pesimista?.</p>
<p>2. Si por ejemplo empleo un DataAdapter (o TableAdapter) para realizar operaciones sobre la base de datos, ¿qué tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.</p>
<p>3. Si por el contrario realizo las operaciones con un objeto de tipo OleDbCommand, en un escenario conectado, ¿que tipo de bloqueo se aplica por defecto?, ¿como lo puedo modificar sin emplear transacciones?.</p>
<p>4. ¿Como puedo implementar el bloqueo de tipo &#8220;el último gana&#8221;?</p>
<p>5. Cuando se emplean transacciones, ¿los niveles de aislamiento definen el tipo de bloqueo?</p>
<p>La verdad esq tengo un poco de &#8220;empanada mental&#8221; con estos estos conceptos. A ver si me lo puedes aclarar un poco. </p>
<p>Gracias y saludos!
<div class="ratingblock ">
<div style="display: none">VA:F [1.7.3_972]</div>
<div id="comment_rater_108" class="ratecmm">
<div class="starsbar">
<div class="gdouter" align="left">
<div id="gdr_vote_c108" style="width: 0px;" class="gdinner"></div>
<div id="gdr_stars_c108" class="gdsr_rating_as"><a id="gdsrX108X5X0XcXcomment_rater_108Xcomment_loader_108" title="5 out of 5" class="s5" rel="nofollow"></a><a id="gdsrX108X4X0XcXcomment_rater_108Xcomment_loader_108" title="4 out of 5" class="s4" rel="nofollow"></a><a id="gdsrX108X3X0XcXcomment_rater_108Xcomment_loader_108" title="3 out of 5" class="s3" rel="nofollow"></a><a id="gdsrX108X2X0XcXcomment_rater_108Xcomment_loader_108" title="2 out of 5" class="s2" rel="nofollow"></a><a id="gdsrX108X1X0XcXcomment_rater_108Xcomment_loader_108" title="1 out of 5" class="s1" rel="nofollow"></a></div>
</div>
</div>
</div>
<div id="comment_loader_108" style="display: none; width:60px;" class="ratingloadercomment">
<div class="loader flower " style="height: 12px">
<div class="loaderinner">aguarde un momento...</div>
</div>
</div>
<div id="gdr_text_c108" class=" comment">Rating: 0.0/<strong>5</strong> (0 votos cast)</div>
</div>
]]></content:encoded>
	</item>
	<item>
		<title>Por: lrocker</title>
		<link>http://www.programandoamedianoche.com/2009/04/transacciones-y-modos-de-aislamiento-en-sql-server-y-adonet/comment-page-1/#comment-42</link>
		<dc:creator>lrocker</dc:creator>
		<pubDate>Wed, 03 Jun 2009 23:05:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.programandoamedianoche.com/?p=278#comment-42</guid>
		<description>Muy buen documento, muchas gracias por la publicación.
Saludos,</description>
		<content:encoded><![CDATA[<p>Muy buen documento, muchas gracias por la publicación.<br />
Saludos,
<div class="ratingblock ">
<div style="display: none">VA:F [1.7.3_972]</div>
<div id="comment_rater_42" class="ratecmm">
<div class="starsbar">
<div class="gdouter" align="left">
<div id="gdr_vote_c42" style="width: 40px;" class="gdinner"></div>
<div id="gdr_stars_c42" class="gdsr_rating_as"><a id="gdsrX42X5X0XcXcomment_rater_42Xcomment_loader_42" title="5 out of 5" class="s5" rel="nofollow"></a><a id="gdsrX42X4X0XcXcomment_rater_42Xcomment_loader_42" title="4 out of 5" class="s4" rel="nofollow"></a><a id="gdsrX42X3X0XcXcomment_rater_42Xcomment_loader_42" title="3 out of 5" class="s3" rel="nofollow"></a><a id="gdsrX42X2X0XcXcomment_rater_42Xcomment_loader_42" title="2 out of 5" class="s2" rel="nofollow"></a><a id="gdsrX42X1X0XcXcomment_rater_42Xcomment_loader_42" title="1 out of 5" class="s1" rel="nofollow"></a></div>
</div>
</div>
</div>
<div id="comment_loader_42" style="display: none; width:60px;" class="ratingloadercomment">
<div class="loader flower " style="height: 12px">
<div class="loaderinner">aguarde un momento...</div>
</div>
</div>
<div id="gdr_text_c42" class=" comment">Rating: 3.3/<strong>5</strong> (3 votos cast)</div>
</div>
]]></content:encoded>
	</item>
</channel>
</rss>
